在c++的类成员的初始化顺序问题上需要注意的是:其成员的初始化顺序不是由构造函数所生命的初始化顺序来决定的,它的初始化顺序是由类中成员数据的生命顺序来进行构造的。现举一例子就会恍然大悟了:
#include <iostream>
class basea
{
public:
basea() {std::cout << "constructor of basea/n";}
~basea() {std::cout << "destructor of basea/n";}
};
class baseb
{
public:
baseb() {std::cout << "constructor of baseb/n";}
~baseb() {std::cout << "destructor of baseb/n";}
};
class test
{
public:
test() : t2(), t1() {} //你认为初始化顺序是t2 t1吗?
~test() {}
private: //注意下面的数据成员的生命顺序,是t1 t2哦
basea t1;
baseb t2;
};
测试结果:
constructor of basea
constructor of baseb
destructor of baseb
destructor of basea
再一个就是基类与派生类中的默认参数问题,如果在派生类中实现基类中的纯虚函数,而基类中已经为此纯虚函数定义了一个默认参数,那么仅仅以基类中所定义的默认参数为标准。也就是说,无论派生类中是否为此函数定义了默认参数,其默认参数均取基类的默认参数。用一个测试程序来测试一下你就会很清楚了:
#include <iostream>
class base
{
public:
virtual void test (int i=0) const = 0;
};
class derived :public base
{
public:
void test(int i = 1) const {std::cout << i << std::endl;}
};
void Test()
{
base *p = new derived;
p->test(); //估计你很肯定的说这里将输出i的值为1,真的是这样吗?
delete p;
};
void main()
{
test t;
}
测试结果:
1
再来就是c++的动态特性与静态特性了。所谓动态特性就是类中的成员函数只能在运行的时候根据派生类以及基类的关系进行动态调用;而静态特性就是在编译阶段就已经确de定了的调用关系,要么调用基类成员函数,要么调用派生类的成员函数,它的特定就是只根据声明的类定来决定是调用基类还是派生类。说了这么多,还是来看看一个测试用例理解上面所说的内容吧:
#include <iostream>
class base
{
public:
virtual void test (void) const {std::cout << "output from base test/n";}
};
class derived :public base
{
public:
void test(void) const {std::cout << "output from derived test/n";}
};
void Test()
{
derived d;
base *pb = &d;
pb->test;
derived *pd = &d;
pd->test;
};
void main()
{
Test();
}
测试结果:
output from derived test
output from derived test
如果把基类的virtual关键字去掉
测试结果:
output from base test
output from derived test
哈哈,现在相信明白上面我所说的有长有乏味的话吧~