Q1:构造函数能否重载,析构函数能否重载,为什么?
A1:函数重载就是同一函数名的不同实现,并且能在编译时能与一具体形式匹配,这样参数列表必须不一样。由于重载函数与普通函数的差别是没有返回值,而返回值不能确定函数重载,所以构造函数可以重载; 析构函数的特点是参数列表为空,并且无返回值,从而不能重载。
例如:
class A
{
public:
A(int n)
{
cout << "call structor A(int n)." << endl;
m_num = n;
}
A(const A &a)
{
cout << "Call structor A(const A &a)." << endl;
}
virtual ~A()
{
cout << "Call destructor ~A()." << endl;
}
A& operator=(const A &a)
{
this->m_num = a.m_num;
return *this;
}
private:
int m_num;
};
{
public:
A(int n)
{
cout << "call structor A(int n)." << endl;
m_num = n;
}
A(const A &a)
{
cout << "Call structor A(const A &a)." << endl;
}
virtual ~A()
{
cout << "Call destructor ~A()." << endl;
}
A& operator=(const A &a)
{
this->m_num = a.m_num;
return *this;
}
private:
int m_num;
};
Q2:析构函数为什么一般情况下要声明为虚函数?
A2:虚函数是实现多态的基础,当我们通过基类的指针是析构子类对象时候,如果不定义成虚函数,那只调用基类的析构函数,子类的析构函数将不会被调用。如果定义为虚函数,则子类父类的析构函数都会被调用。
例如:
class B:public A
{
public:
B(int n):A(n)
{
cout << "call structor B(int n)." << endl;
}
~B()
{
cout << "Call destructor ~B()." << endl;
}
};
{
public:
B(int n):A(n)
{
cout << "call structor B(int n)." << endl;
}
~B()
{
cout << "Call destructor ~B()." << endl;
}
};
void main(void)
{
A *pa = new B(10);
delete pa;
}
{
A *pa = new B(10);
delete pa;
}
输出为:
call structor A(int n).
call structor B(int n).
Call destructor ~B().
Call destructor ~A().
call structor B(int n).
Call destructor ~B().
Call destructor ~A().
修改calss A的析构函数,如下:
~A()
{
cout << "Call destructor ~A()." << endl;
}
{
cout << "Call destructor ~A()." << endl;
}
如果非虚函数,输出为:
call structor A(int n).
call structor B(int n).
Call destructor ~A().
call structor B(int n).
Call destructor ~A().
Q3:什么情况下必须定义拷贝构造函数?
A3:当类的对象用于函数值传递时(值参数,返回类对象),拷贝构造函数会被调用。如果对象复制并非简单的值拷贝,那就必须定义拷贝构造函数。例如大的堆栈数据拷贝。如果定义了拷贝构造函数,那也必须重载赋值操作符。