我对以下代码的输出很困惑:
#include <iostream>
using namespace std;
class Parent
{
public:
Parent() : x(2) { }
virtual ~Parent() { }
void NonVirtual() { cout << "Parent::NonVirtual() x = " << x << endl; }
private:
int x;
};
class Child : public Parent
{
public:
Child() : x(1) { }
virtual ~Child() { }
void NonVirtual() { cout << "Child::NonVirtual() x = " << x << endl; }
private:
int x;
};
int main()
{
Child c;
Parent* p = &c;
c.NonVirtual(); // Output: Child::NonVirtual() x = 1
p->NonVirtual(); // Output: Parent::NonVirtual() x = 2
// Question: are there two x'es in the Child object c?
// where is x = 2 from (we have not defined any Parent object)?
cout << sizeof(c) << endl;
cout << sizeof(*p) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码说明了这样一个事实,即在C++中,只有标记virtual
的函数才会被覆盖.你在这里所拥有的是黯然失色,而不是压倒一切.在重写和继承中,行为基于运行时类型,这是您期望的正常继承行为,但如果您不将其声明为虚拟,那么该行为完全基于编译时类型(即声明的类型).由于p被声明为Parent*类型,它使用Parent中的实现,而c被声明为Child类型,因此它使用Child类型给出的版本.如果您将方法声明为virtual,那么在这两种情况下,它都会在运行时查找该函数的相应版本并调用Child类中给出的版本.
我还应该补充一点,你有两个不同的x变量...如果你想在基类和派生类之间共享变量,你应该在基类中将它标记为"受保护"(尽管我认为它通常很差)设计这样做).您在Child中声明的x变量是与Parent中的变量不同的变量.请记住,x在Parent中是私有的,因此在Child中创建名为x的第二个变量之前,名称x在Child中没有任何意义.
归档时间: |
|
查看次数: |
714 次 |
最近记录: |