C++进阶--构造函数和析构函数中的虚函数

//############################################################################
/*
任何时候都不要在构造函数或析构函数中调用虚函数
*/
class dog {
    public:
        string m_name;
        dog(string name) {m_name = name;  bark();}
        virtual void bark() { cout<< "Woof, I am just a dog " << m_name << endl;}
};

class yellowdog : public dog {
    public:
        yellowdog(string name) : dog(string name) {...}
        virtual void bark() { cout << "Woof, I am a yellow dog " << m_name << endl; }
};

int main ()
{
  yellowdog mydog("Bob");
}


输出:
Woof, I am just a dog Bob.

/*
在构造的过程中,所有虚函数表现为非虚函数

为什么?
基类在派生类之前构造。
所以bark()的时候,yellowdog还没有构造


为什么Java中表现不一样?

Java和C++在定义对象的生命周期上有一个基本的差异
Java: 所有成员在构造函数运行前被null初始化。生命周期在构造函数之前已经开始
C++: 构造函数负责初始化成员。生命周期在构造函数结束之后才开始

调用对象中还未被初始化的部分是继承危险的
调用对象中已经被delete的部分也是危险的
*/


/*
解决方法 1:
不使用多态,使用初始化参数来产生运行时差异
*/
class dog {
    public:
        ...
        dog(string name, string color) {m_name = name; bark(color);}
        void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;}
};

class yellowdog : public dog {
    public:
        yellowdog(string name):dog(name, "yellow") {}
};

int main ()
{
  yellowdog mydog("Bob");
}

输出:
Woof, I am yellow dog Bob


/*
解决方法 2:
使用私有静态成员函数,不同派生类可执行不同操作
*/
class dog {
    public:
        ...
        dog(string name, string woof) {m_name = name; bark(woof);}
        dog(string name) {m_name = name; bark( getMyColor() );}
        void bark(string str) { cout<< "Woof, I am "<< str << " dog " << m_name << endl;}
    private:
        static string getMyColor() {return "just a";} 
};

class yellowdog : public dog {
    public:
        yellowdog(string name):dog(name, getMyColor()) {}
    private:
        static string getMyColor() {return "yellow";}  //Why static? 
};

int main ()
{
  yellowdog mydog("Bob");
}
OUTPUT:
Woof, I am yellow dog Bob

猜你喜欢

转载自www.cnblogs.com/logchen/p/10165346.html