C++面向对象的特性面试题目23例

1、是不是一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态?

【参考答案】
virtual修饰符会被隐形继承的。virtual可加可不加。子类的空间里有父类的所有变量(static除外)。同一个函数只存在一个实体(inline除外)。子类覆盖它的函数不加virtual ,也能
实现多态。在子类的空间里,有父类的私有变量。私有变量不能直接访问。

2、面向对象的三个基本特征,并简单叙述之?

【参考答案】                                                                     
1. 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private, protected, public)                  
2. 继承:广义的继承有三种实现形式:
实现继承(指使用基类的属性和方法而无需额外编码的能力)、
可视继承(子窗体使用父窗体的外观和实现代码)、
接口继承(仅使用属性和方法,实现滞后到子类实现)。
前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。                                 
3. 多态:是将父对象设置成为和一个或更多的与他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。

3、重载(overload)、重写(override,有的书也叫做“覆盖”)、重定义(redefinition)的区别?

【标准答案】
重载    同一名字空间  是指允许存在多个同名函数,而这些函数的参数表不同。
重定义/隐藏  不同名字空间 用于继承,派生类与基类的函数同名,屏蔽基类的函数
重写/覆盖 不同名字空间
用于继承,子类重新定义父类虚函数的方法

4、多态的作用?

【参考答案】
主要是两个:
1. 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
2. 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。

5、当一个类A 中没有声命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。

【标准答案】
sizeof(A) = 1;

6、如果 ClassA 中定义并实现虚函数 int func(void),ClassB 中也实现该函数,那么上述变量 a->func() 将调用哪个类里面的函数?如果 int func(void) 不是虚函数,情况又如何?为什么?

【参考答案】
第一问调用的是B的。第二问调用A的。
虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果。

7、 C++里面是不是所有的动作都是main()引起的?如果不是,请举例。

【参考答案】
比如全局变量的初始化,就不是由 main 函数引起的。举例:        

class   A{

};

A   a;   //a的构造函数限执行

int   main() {

}

复制代码

8、 内联函数在编译时是否做参数类型检查

【参考答案】
内联函数要做参数类型检查,   这是内联函数跟宏相比的优势。                                                                 

9、请讲一讲析构函数和虚函数的用法和作用? 

【参考答案】
析构函数是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类对象的生命期结束的时候,由系统自动调用。
有适放内存空间的作用。
虚函数是C++多态的一种表现, 使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。

10、“new”in c++ is a?

A. library function like malloc in c 
B. key word
C. operator
D. none of the above
【参考答案】C。
malloc是库函数,不在编译器控制范围之内;new是运算符,在编译器控制范围之内。   
调用malloc时,从堆中申请内存;调用new时,从堆中申请内存并为内存调用构造函数。

11、对于C++中类(class) 与结构(struct)的描述正确的为:

A、类中的成员默认是private的,但是可以声明public,private 和 protected,结构中定义的成员默认的都是public;
B、结构中不允许定义成员函数,但是类中可以定义成员函数;
C、结构实例使用malloc() 动态创建,类对象使用new 操作符动态分配内存;
D、结构和类对象都必须使用new 创建;
E、结构中不可以定义虚函数,但是类中可以定义虚函数.
F、结构不可以存在继承关系,但是类可以存在继承关系.
【标准答案】A,D

12、两个互相独立的类:ClassA 和 ClassB,都各自定义了非静态的公有成员函数 PublicFunc() 和非静态的私有成员函数 PrivateFunc(); 现在要在ClassA 中增加定义一个成员函数ClassA::AdditionalPunction(ClassA a,ClassB b);则可以在AdditionalPunction(ClassA x,ClassB y)的实现部分(函数功能体内部)出现的合法的表达是最全的是:

A、x.PrivateFunc();x.PublicFunc();y.PrivateFunc();y.PublicFunc();
B、x.PrivateFunc();x.PublicFunc();y.PublicFunc();
C、x.PrivateFunc();y.PrivateFunc();y.PublicFunc();
D、x.PublicFunc();y.PublicFunc();
【标准答案】B

13、C++程序下列说法正确的有:

A、对调用的虚函数和模板类都进行迟后编译.
B、基类与子类中函数如果要构成虚函数,除了要求在基  类中用virtual 声名,而且必须名字相同且参数类型相同返回类型相同。
C、重载的类成员函数都必须要:或者返回类型不同,或者参数数目不同,或者参数序列的类型不同.
D、静态成员函数和内联函数不能是虚函数,友员函数和构造函数也不能是虚函数,但是析构函数可以是虚函数.
【标准答案】A

14、在C++中有没有纯虚构造函数? 

【标准答案】构造函数不能是虚的。只能有虚的析构函数。

15、下面的 throw 表达式哪些是错误的?

(a) class exceptionType { }; 
     throw exceptionType { }; 
(b) enum mathErr { overflow, underflow, zeroDivide }; 
    throw zeroDivide(); 
【标准答案】
(a) class exceptionType { }; 
     throw exceptionType();
(b) enum mathErr { overflow, underflow, zeroDivide }; 
    throw zeroDivide; 

16、谈谈你是怎么认识 C++ 中的模板的?

【参考答案】
模板使程序员能够快速建立具有类型安全的类库集合和函数集合,它的实现,方便了大规模的软件开发。(结合stl更好)

17、在 C++的一个类中声明一个 static 成员变量有没有用?

【参考答案】
在C++类的成员变量被声明为 static(称为静态成员变量),意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,
也就是说不管创建多少对象,static修饰的变量只占有一块内存。其修改值为该类的其它所有实例所见;而类的静态成员函数也只能访问静态成员(变量或函数)。static是加了访问控制的全局变量,不被继承。

18、C++中为什么用模板类?

【参考答案】
(1)可用来创建动态增长和减小的数据结构
(2)它是类型无关的,因此具有很高的可复用性。
(3)它在编译时而不是运行时检查数据类型,保证了类型安全(4)它是平台无关的,可移植性(5)可用于基本数据类型

19、函数模板与类模板有什么区别?

【参考答案】
函数模板的实例化是由编译程序在处理函数调用时自动完成的,而类模板的实例化必须由程序员在程序中显式地指定。

20、请你谈谈你在类中如何使用 const 的。

【参考答案】
有时我们希望某些常量只在类中有效。由于#define 定义的宏常量是全局的,不能达到目的,于是想当然地觉得应该用 const 修饰数据成员来实现。
const 数据成员的确是存在的,但其含义却不是我们所期望的。const 数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的,因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。 不能在类声明中初始化 const 数据成员。

const 数据成员的初始化只能在类构造函数的初始化表中进行。

21、函数重载,我们靠什么来区分调用的那个函数?靠返回值判断可以不可以?

【参考答案】
如果同名函数的参数不同(包括类型、顺序不同) ,那么容易区别出它们是不同的。如果同名函数仅仅是返回值类型不同,有时可以区分,有时却不能。例如: 
void Function(void); 
int  Function (void); 
上述两个函数,第一个没有返回值,第二个的返回值是 int 类型。如果这样调用函数: 
int  x = Function (); 
则可以判断出 Function 是第二个函数。问题是在 C++/C 程序中,我们可以忽略函数的返回值。在这种情况下,编译器和程序员都不知道哪个 Function 函数被调用。 所以只能靠参数而不能靠返回值类型的不同来区分重载函数。

22、所有的运算符都能重载吗?

【参考答案】
不能被重载的运算符 
在 C++运算符集合中,有一些运算符是不允许被重载的。这种限制是出于安全方面的考虑,可防止错误和混乱。 
(1)不能改变 C++内部数据类型(如 int,float 等)的运算符。 
(2)不能重载‘.’,因为‘.’在类中对任何成员都有意义,已经成为标准用法。 
(3)不能重载目前 C++运算符集合中没有的符号,如#,@,$等。原因有两点,一是难以理解,二是难以确定优先级。 
(4)对已经存在的运算符进行重载时,不能改变优先级规则,否则将引起混乱。 

23、基类的析构函数不是虚函数,会带来什么问题?

【参考答案】
派生类的析构函数用不上,会造成资源的泄漏。

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
面向对象程序设计》试题 一、单选题(每空2分,共40分) 1、关于C++与C语言关系的描述中,( )是错误的。 A.C语言C++语言的一个子集 B.C语言C++语言是兼容的 C.C++语言对C语言进行了一些改进 D.C++语言和C语言都是面向对象的 2、已知:int m=10; 下列表示引用的方法中,( )是正确的。 A.int& x=m; B.int& y=10; C.int& z; D.float& t=&m; 3、考虑下面的函数原型声明: void DefPar(int a, int b=7, char z = '*'); 下面函数调用中,不合法的是( )。 A.DefPar(5); B.DefPar(5,8); C.DefPar(5,'#'); D.DefPar(0,0,'*'); 4、系统在调用重载函数时往往根据一些条件确定哪个重载函数被调用,在下列选项中,不能作为依据的是( )。 A.函数的返回值类型 B.参数的类型 C.函数名称 D.参数个数 5、下列有关C++类的说法中,不正确的是( )。 A.类是一种用户自定义的数据类型 B.只有类中的成员函数或类的友元函数才能存取类中的私有成员 C.在类中,如果不做特别说明,所有成员的访问权限均为私有的 D.在类中,如果不做特别说明,所有成员的访问权限均为公用的 6、已知X类,则当程序执行到语句X array[3];时,调用了( )次构造函数。 A.0 B.1 C.2 D.3 7、有关析构函数的说法,不正确的是( )。 A.析构函数有且仅有一个 B.析构函数和构造函数一样可以有形参 C.析构函数的功能是在系统释放对象之前作一些内存清理工作 D.析构函数无任何函数类型 8、类定义的内容允许被其对象无限制地存取的是( )。 A.private 部分 B. protected 部分 C.public 部分 D.以上都不对 9、关于常数据成员的说法,不正确的是( )。 A.常数据成员的定义形式与一般常变量的,只不过常数据成员的定义必须出现在类体中 B.常数据成员必须进行初始化,并且不能被更新 C.常数据成员通过构造函数的成员初始化列表进行初始化 D.常数据成员可以在定义时直接初始化 10、运用运算符delete删除一个动态对象时( )。 A.系统首先为该动态对象调用构造函数,再释放其占用的内存 B.系统首先释放该动态对象占用的内存,再为其调用构造函数 C.系统首先为该动态对象调用析构函数,再释放其占用的内存 D.系统首先释放动态对象占用的内存,再为其调用析构函数 11、可在类外用p.a的形式访问派生类对象 p的基类成员a,其中a是( )。 A.私有继承的公用成员 B.公用继承的私有成员 C.公用继承的保护成员 D.公用继承的公用成员 12、在公用继承方式下,有关派生类对象和基类对象的关系,不正确的叙述是(  )。 A.派生类的对象可以赋给基类的对象 B.派生类的对象可以初始化基类的引用 C.派生类的对象可以直接访问基类中的成员 D.派生类的对象的地址可以赋给指向基类的指针 13、设置虚基类的的是( )。 A.简化程序 B.消除二义性 C.提高运行效率 D.减少标代码 14、在C++中,用于实现动态多态性的是( )。 A.内联函数 B.重载函数 C.模板函数 D.虚函数 15、不能说明为虚函数的是( )。 A.析构函数 B.构造函数 C.类的成员函数 D.以上都不对 16、如果一个类至少有一个纯虚函数,那么就称该类为( )。 A.抽象类 B.派生类 C.纯基类 D.以上都不对 17、下面关于友元的描述中,错误的是( )。 A.友元函数可以访问该类的私有数据成员 B.一个类的友元类中的成员函数都是这个类的友元函数 C.友元可以提高程序的运行效率 D.类与类之间的友元关系可以继承 18、下列运算符中,( )运算符在C++中不能被重载。 A.&& B.[ ] C.:: D.new 19、模板的使用实际上是将类模板实化成一个( )。 A.函数 B.对象 C.类 D.抽象类 20、假定MyClass为一个类,则该类的拷贝构造函数的声明语句为( )。 A.MyClass(MyClass x) B.MyClass&(MyClass x) C.MyClass(MyClass &x) D.MyClass(MyClass *x) 二、填空题(前16个空,每空1分,后2个空,每空2分,共20分) 1、类和对象的关系可表述为:类是对象的 ,而对象则是类的 。 2、在C++中,三种继承方式的说明符号为 、 和 ,如果不加说明,则默认的继承方式为 。 3、如果只想保留公共基类的一个复制,就必须使用关键字 把这个公共基类声明为虚基类。 4、若要把void fun( )定义为类A的友元函数,则应在类A的定义中加入语句 。 5、类的静态成员分为 和 。 6、运算符重载要求保持其原来的操作数个数、 、 和语法结构。 7、通过关键字 可以声明模板,通过关键字 指定函数模板的类型参数,有几个类型参数就有几个类型关键字。 8、列出C++中两种用户自定义的数据类型: 、 。 9、构造函数的作用是 。 10、后置自增运算符“++”重载为类的成员函数(设类名为A)的形式为 。 三、阅读下面3个程序,写出程序运行时输出的结果:(共13分) 1、#include <iostream> using namespace std; void fun(int &a,int &b) { int p; p=a; a=b; b=p; } void exchange(int &a,int &b,int &c) { if(a<b) fun(a,b); if(a<c) fun(a,c); if(b<c) fun(b,c); } void main() { int a=12,b=89,c=56; exchange(a,b,c); cout<<"a="<<a<<",b="<<b<< ",c="<<c<<endl; } 2、#include <iostream> using namespace std; class Date { public: Date(int,int,int); Date(int,int); Date(int); Date(); void display(); private: int month, day, year; }; Date::Date(int m, int d, int y) : month(m),day(d),year(y) { } Date::Date(int m,int d):month(m),day(d) { year=2009; } Date::Date(int m) : month(m) { day=1; year=2010; } Date::Date() { month=1; day=1; year=2010; } void Date::display() { cout <<month<<"/"<<day<<"/"<<year<<endl; } void main() { Date d1(12,31,2009); Date d2(12,31); Date d3(1); Date d4; d1.display(); d2.display(); d3.display(); d4.display(); } 3、#include <iostream> using namespace std; class A { public: A() { cout<<"constructing A "<<endl; } ~A() { cout<<"destructing A "<<endl; } }; class B: public A { public: B() { cout<<"constructing B "<<endl; } ~B() { cout<<"destructing B "<<endl; } }; class C : public B { public: C() { cout<<"constructing C "<<endl; } ~C() { cout<<"destructing C "<<endl; } }; void main() { C c1; } 四、编程题(共27分) 1、(10分)已知复数类Complex的声明如下: class Complex { public: Complex(); Complex(double); Complex(double, double); friend Complex operator + (Complex&, Complex&); friend ostream & operator << (ostream&, Complex&); friend istream& operator >> (istream&, Complex&); private: double real, imag; }; 要求: (1)写出该类的所有构造函数的类外定义代码。 (2)写出对运算符“+”、“<<”、“>>”进行重载的运算符重载函数的定义。 2、(17分)下列Base类是一个表示形状的抽象类,area( )为求图形面积的函数,total( )则是一个通用的用以求不同形状的图形面积总和的函数。 class Base { public: virtual double area()=0; }; double total(Base *s[ ], int n) { double sum=0.0; for(int i=0; i<n; i++) sum+=s[i]->area( ); return sum; } 要求: (1)从Base类派生圆类(Circle)、正方形类(Square),圆类新增数据成员半径(radius),正方形类新增数据成员边长(a),圆类和正方形类都有构造函数,修改、显示数据成员值的函数,求面积函数。 (2)写出main( )函数,计算半径为5.5的圆和边长为9.9的正方形的面积和(必须通过调用total函数计算)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值