//############################################################################
/*
任何时候都不要在构造函数或析构函数中调用虚函数
*/
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
C++进阶
点赞
收藏