前言
面向对象编程的三个基本特征:封装、继承和多态。子类和父类有同名的成员?会出现什么样的行为。
内容
如果父类和子类都有一个成员,返回哪一个?
case 1:没有虚函数,没有多态 => 通过父类的指针输出的是父类的值
class Base {
public:
Base() : value(10) {}
int getValue() { return value; }
int value;
};
class Sub :public Base {
public:
Sub() : value(20) {}
int getValue() { return value; }
int value;
};
int main()
{
Base* pBase = new Sub();
std::cout << "pBase->value:" << pBase->value << ", " << pBase->getValue() << std::endl;
}
结果:
case 2: 有虚函数,有多态 => 通过父类的指针输出的是父类的value,和子类的 getValue;通过子类的指针输出的是子类的value,和子类的getValue。
class Base {
public:
Base() : value(10) {}
virtual int getValue() { return value; } // 虚函数
int value;
};
class Sub :public Base {
public:
Sub() : value(20) {}
int getValue() { return value; }
int value;
};
int main()
{
Base* pBase = new Sub();
// pBase->getValue() 调用的是 Sub::getValue。Sub::getValue 返回的是 Sub::value。
std::cout << "pBase->value:" << pBase->value << ", " << pBase->getValue() << std::endl;
Sub* pSub = dynamic_cast<Sub*>(pBase);
if (pSub)
{
std::cout << "pSub->value:" << pSub->value << ", " << pSub->getValue() << std::endl;
}
}
结果:
注意:如果父类接口没有虚函数,即没有 virtual
,不能使用 dynamic_cast
。
如果函数本身被 const 修饰,本质上就是两个函数
class Base {
public:
Base() : value(10) {}
virtual int getValue() const { return value; } // 这里有 const 修饰符
int value;
};
class Sub :public Base {
public:
Sub() : value(20) {}
int getValue() { return value; } // 这里没有 const 修饰符
int value;
};
int main()
{
Base* pBase = new Sub();
std::cout << "pBase->value:" << pBase->value << ", " << pBase->getValue() << std::endl; // 都是父类的
Sub* pSub = dynamic_cast<Sub*>(pBase);
if (pSub)
{
std::cout << "pSub->value:" << pSub->value << ", " << pSub->getValue() << std::endl; // 都是子类的
}
}
结果:
注意:
成员函数是否带 const
,是两个不同的函数。
class Base {
public:
Base() : value(10) {}
virtual int getValue() const { return value; }
virtual int getValue() { return value; }
int value;
};