我有一个关于继承和虚方法的基本C ++问题。
请注意此代码:
#include <iostream>
#include <vector>
using namespace std;
class A {
public:
virtual void f() {cout << "A\n";};
};
class B : public A {
public:
void f() {cout << "B\n";};
};
int main() {
A a;
B b;
vector<A> v;
v.push_back(a);
v.push_back(b);
for (int i = 0; i < v.size(); ++i)
v.at(i).f();
}
如果我执行此代码,则会打印出
A
A
我不明白为什么不打印
A
B
因为&#34; f&#34;方法声明为虚拟。 我想知道为什么程序会以这种方式运行。
提前致谢
答案 0 :(得分:6)
您的矢量包含A
个对象:
vector<A> v;
当您将B
对象推入其中时,该向量会将其A
部分复制到新的A
对象中。这相当于这样做:
A a;
B b;
a = b;
a.f();
这称为object slicing。
答案 1 :(得分:3)
您是slicing对象,您需要使用指针或references才能正常运行。使用指针的示例:
int main()
{
vector<A*> v;
v.push_back(new A);
v.push_back(new B );
for (int i = 0; i < v.size(); ++i)
v[i]->f();
}
这将为您提供所需的polymorphic
行为并具有此输出:
A
B
答案 2 :(得分:2)
b
被复制到A
的实例,当它被复制以插入vector
时,您必须使用vector<A*>
才能按预期工作。
答案 3 :(得分:0)
你应该有指针的向量,以便具有多态行为:)
答案 4 :(得分:0)
在C ++中,只有指针和对象的引用才具有多态性。您的向量包含A类型的非多态对象。
试
int main() {
A a;
B b;
vector<A*> v;
v.push_back(&a);
v.push_back(&b);
for (int i = 0; i < v.size(); ++i)
v.at(i)->f();
虽然您需要注意,当a和b被销毁时(当它们超出范围时),这些指针将变为无效。
答案 5 :(得分:0)
向量v包含类型A的对象。当您将对象推回到v时,这些对象使用A的复制构造函数进行实例化。就像稍后在函数f for上调用的每个对象实际上是类型A和永远不会执行B的f()。