C++ 覆盖基本成员值
C++ Override base member value
我有以下代码:
class A
{
public:
int foo = 0;
};
class B: public A
{
public:
int foo = 1;
};
int main()
{
A *a = new B();
std::cout << a->foo;
std::getchar();
return 0;
}
输出:0
为什么 B 不覆盖 A 的成员 foo ?
以及如何在不转换为派生的情况下获得所需的 1 输出 class
您只能重写 virtual
个成员函数。
所有其他成员,无论是函数、类型还是成员变量,都只能是 shadowed.
这意味着它们根本没有改变,但如果不引用正确的基础、使用范围解析运算符等就不容易访问。
所以,改为使用虚函数而不是成员变量。
使用虚函数。你不能有虚拟字段,因此你得到的值是你的实例指针的类型(A
)而不是所指向的真实类型(B
)。
#include <iostream>
using namespace std;
class A
{
int foo_ = 0;
public:
virtual int foo() const { return foo_; }
virtual ~A(){}
};
class B: public A
{
int foo_ = 1;
public:
virtual int foo() const { return foo_; }
};
int main()
{
A *a = new A();
A *b = new B();
cout << a->foo() << '\n';
cout << b->foo() << '\n';
cin.ignore();
delete a;
delete b;
}
B::foo
是一个完全独立于 A::foo
的成员。这就是为什么初始化 B::foo
不会更新 A::foo
。您将不得不做更多类似的事情:
class
{
public:
int foo;
A(int value = 0) : foo(value) {}
};
class B : public A
{
public:
B() : A(1) {}
};
int main()
{
A *a = new B();
std::cout << a->foo;
delete a;
std::getchar();
return 0;
}
如果您想使用多态行为,您可以为您的成员变量 "foo" 编写一个虚拟 getter 方法,因为不能直接多态访问数据成员。
您在下面修改了您的示例代码片段以实现该目的-
class A
{
int foo;
public:
A() { foo = 0; }
virtual int getFoo() { return foo; }
};
class B: public A
{
int foo;
public:
B() { foo = 1; }
virtual int getFoo() { return foo; }
};
int main()
{
A *a = new B();
std::cout << a->getFoo();
std::getchar();
return 0;
}
我有以下代码:
class A
{
public:
int foo = 0;
};
class B: public A
{
public:
int foo = 1;
};
int main()
{
A *a = new B();
std::cout << a->foo;
std::getchar();
return 0;
}
输出:0
为什么 B 不覆盖 A 的成员 foo ?
以及如何在不转换为派生的情况下获得所需的 1 输出 class
您只能重写 virtual
个成员函数。
所有其他成员,无论是函数、类型还是成员变量,都只能是 shadowed.
这意味着它们根本没有改变,但如果不引用正确的基础、使用范围解析运算符等就不容易访问。
所以,改为使用虚函数而不是成员变量。
使用虚函数。你不能有虚拟字段,因此你得到的值是你的实例指针的类型(A
)而不是所指向的真实类型(B
)。
#include <iostream>
using namespace std;
class A
{
int foo_ = 0;
public:
virtual int foo() const { return foo_; }
virtual ~A(){}
};
class B: public A
{
int foo_ = 1;
public:
virtual int foo() const { return foo_; }
};
int main()
{
A *a = new A();
A *b = new B();
cout << a->foo() << '\n';
cout << b->foo() << '\n';
cin.ignore();
delete a;
delete b;
}
B::foo
是一个完全独立于 A::foo
的成员。这就是为什么初始化 B::foo
不会更新 A::foo
。您将不得不做更多类似的事情:
class
{
public:
int foo;
A(int value = 0) : foo(value) {}
};
class B : public A
{
public:
B() : A(1) {}
};
int main()
{
A *a = new B();
std::cout << a->foo;
delete a;
std::getchar();
return 0;
}
如果您想使用多态行为,您可以为您的成员变量 "foo" 编写一个虚拟 getter 方法,因为不能直接多态访问数据成员。
您在下面修改了您的示例代码片段以实现该目的-
class A
{
int foo;
public:
A() { foo = 0; }
virtual int getFoo() { return foo; }
};
class B: public A
{
int foo;
public:
B() { foo = 1; }
virtual int getFoo() { return foo; }
};
int main()
{
A *a = new B();
std::cout << a->getFoo();
std::getchar();
return 0;
}