C++之面试常问:类
目录
3. 编写类String 的构造函数,析构函数,拷贝构造函数和赋值函数
12. 有哪几种情况只能用构造函数初始化列表而不能用赋值初始化?
13. C++如何阻止一个类被实例化?一般在什么时候将构造函数声明为private?
14. 多态类中的虚函数表是 Compile-Time,还是 Run-Time时建立的?
1. struct和class有什么区别?
事实上,C++中保留struct的关键字是为了使C++编译器能够兼容C开发的程序。
分以下所示两种情况。
C的struct与C++的class的区别:struct只是作为一种复杂数据类型定义, 因此不能包含任何函数。
C++中的struct和class的区别:对于成员访问权限以及继承方式,class中默认的是private的,而struct中则是public的。class还可以用于表示模板类型,struct则不行。
2. 类的三种访问属性?
在一个类中,有三种不同访问属性的成员:public、protected、private。
在类的内部(类的声明和类的定义)可以访问public、protected、private所有成员
在类的外部(对象和其他函数)不能访问private和protected成员
在继承中的三种不同的派生方式,对派生类对基类成员的访问属性得改变:
public:
public ->public;
protected->protected;
private->不可访问;
protected:
public->protected;
protected->protected;
private->不可访问;
private:
public->private;
protected->private;
private->不可访问;
基类成员在派生类中的访问属性按照上面的方式改变,改变之后继承自基类的private成员在派生类中不能被访问,只能通过基类的protected或者public成员函数访问。而其他的访问方式同本文开头。
3. 编写类String 的构造函数,析构函数,拷贝构造函数和赋值函数
4. C++空类默认有哪些成员函数?
默认构造函数、析构函数、复制构造函数、赋值运算符重载函数、取址运算符重载函数、const取址运算符重载函数。
5. 继承层次中,为什么基类析构函数是虚函数
编译器总是根据类型来调用类成员函数。但是一个派生类的指针可以安全地转化为一个基类的指针。这样删除一个基类的指针的时候,C++不管这个指针指向一个基类对象还是一个派生类的对象,调用的都是基类的析构函数而不是派生类的。如果你依赖于派生类的析构函数的代码来释放资源,而没有重载析构函数,那么会有资源泄漏。
6. 如果虚函数是有效的,那为什么不把所有函数设为虚函数?
不行。虚函数是有代价的,由于每个虚函数的对象都要维护一个虚函数表,因此在使用虚函数的时候都会产生一定的系统开销,这是没有必要的。
7.面向对象技术的基本概念是什么,三个基本特征是什么?
基本概念:类、对象、继承;
基本特征:封装、继承、多态。
封装:将低层次的元素组合起来形成新的、更高实体的技术;
继承:广义的继承有三种实现形式:实现继承、可视继承、接口继承。
多态:允许将子类类型的指针赋值给父类类型的指针
8. 为什么构造函数不能为虚函数?
虚函数采用一种虚调用的方法。虚调用是一种可以在只有部分信息的情况下工作的机制。如果创建一个对象,则需要知道对象的准确类型,因此构造函数不能为虚函数。
9. 构造函数可以是内联函数
10.什么是多态?多态有什么作用?
多态就是将基类类型的指针或者引用指向派生类型的对象。多态通过虚函数机制实现。
多态的作用是接口重用。
11. 重载和覆盖有什么区别?
虚函数是基类希望派生类重新定义的函数,派生类重新定义基类虚函数的做法叫做覆盖;
重载就在允许在相同作用域中存在多个同名的函数,这些函数的参数表不同。重载的概念不属于面向对象编程,编译器根据函数不同的形参表对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。
重载的确定是在编译时确定,是静态的;虚函数则是在运行时动态确定。
12. 有哪几种情况只能用构造函数初始化列表而不能用赋值初始化?
常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化。
13. C++如何阻止一个类被实例化?一般在什么时候将构造函数声明为private?
(1)将类定义为抽象基类或者将构造函数声明为private;
(2)不允许类外部创建类对象,只能在类内部创建对象
14. 多态类中的虚函数表是 Compile-Time,还是 Run-Time时建立的?
虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组。而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。
15. 一个父类写了一个 virtual 函数,如果子类覆盖它的函数不加 virtual ,也能实现多态?在子类的空间里,有没有父类的这个函数,或者父类的私有变量? (华为笔试题)
只要基类在定义成员函数时已经声明了 virtue关键字,在派生类实现的时候覆盖该函数时,virtue关键字可加可不加,不影响多态的实现。子类的空间里有父类的所有变量(static除外)。