引申:拷贝构造函数在哪些情况下被调用?
(1)函数的参数为类对象且参数采用值传递方式;
(2)将类对象做为函数的返回值。
C++中的explicit关键字有何作用?
解答:禁止将构造函数作为转换函数,即禁止构造函数自动进行隐式类型转换。
例如CBook中只有一个参数m_price,在构建对象时可以使用CBook c = 9.8这样的隐式转换,使用explicit防止这种转换发生。
在C++中,如果确定了某一个构造函数的创建过程,在该构造函数中如果调用了其它重载的构造函数,它将不会执行其它构造函数的初始化列表部分代码,而是执行函数体代码,此时已经退化成普通函数了。例子说明如下:
class CBook {
public:
double m_price;
CBook() {
CBook(8.8);
}
CBook(double price) : m_price(price) { }
};
int main() {
CBook c;
cout << c.m_price << endl; // 此时并不会输出理想中的8.8
}静态数据成员只能在全局区域进行初始化,而不能在类体中进行(构造函数中初始化也不行),且静态数据成员不涉及对象,因此不受类访问限定符的限制。
例子说明如下:
class CBook {
public:
static double m_price;
};
double CBook::m_price = 8.8; // 只能在这初始化,不能在CBook的构造函数或直接初始化C++中可以重载的运算符:new/delete、new[]/delete[]、++等。
不可以重载的运算符:、.、::、?:、sizeof、typeid、.、**、不能改变运算符的优先级。
引申:重载++和?时是怎么区分前缀++和后缀++的?
例如当编译器看到++a(先自增)时,它就调用operator++(a);
但当编译器看到a++时,它就调用operator++(a, int)。即编译器通过调用不同的函数区别这两种形式。
C++的多态性分为静态多态和动态多态。
静态多态性:编译期间确定具体执行哪一项操作,主要是通过函数重载和运算符重载来实现的;
动态多态性:运行时确定具体执行哪一项操作,主要是通过虚函数来实现的。
虚函数原理考点,例如下面程序的输出是什么?
class A {
public:
virtual void funa();
virtual void funb();
void func();
static void fund();
static int si;
private:
int i;
char c;
};问:sizeof(A) = ?
解答:
关于类占用的内存空间,有以下几点需要注意:
(1)如果类中含有虚函数,则编译器需要为类构建虚函数表,类中需要存储一个指针指向这个虚函数表的首地址,注意不管有几个虚函数,都只建立一张表,所有的虚函数地址都存在这张表里,类中只需要一个指针指向虚函数表首地址即可。
(2)类中的静态成员是被类所有实例所共享的,它不计入sizeof计算的空间
(3)类中的普通函数或静态普通函数都存储在栈中,不计入sizeof计算的空间
(4)类成员采用字节对齐的方式分配空间
答案:12(32位系统)或16(64位系统)
虚继承的作用是什么?
在多继承中,子类可能同时拥有多个父类,如果这些父类还有相同的父类(祖先类),那么在子类中就会有多份祖先类。例如,类B和类C都继承与类A,如果类D派生于B和C,那么类D中就会有两份A。为了防止在多继承中子类存在重复的父类情况,可以在父类继承时使用虚函数,即在类B和类C继承类A时使用virtual关键字,例如:
class B : virtual public A
class C : virtual public A
注:因为多继承会带来很多复杂问题,因此要慎用。