以下是我的代码,
#include<iostream>
#include<string>
using namespace std;
class TestClass
{
public:
virtual void test(string st1, string st2);
};
class ExtendedTest: public TestClass
{
public:
virtual void test(string st1, string st2);
};
void TestClass::test(string st1, string st2="st2")
{
cout << st1 << endl;
cout << st2 << endl;
}
void ExtendedTest::test(string st1, string st2="st2")
{
cout << "Extended: " << st1 << endl;
cout << "Extended: " << st2 << endl;
}
void pass(TestClass t)
{
t.test("abc","def");
}
int main()
{
ExtendedTest et;
pass(et);
return 0;
}
当我运行代码时,会调用基类的方法('test')。 但我希望调用子方法,因为我将方法指定为虚函数。
然后如何调用子类的方法?谢谢。
答案 0 :(得分:3)
void pass(TestClass t)
{
t.test("abc","def");
}
执行此操作时,您传递的对象会TestClass
TestClass
并且其身份会丢失,因此它现在的行为类似于t
并相应地调用该方法。< / p>
要修复此问题,您希望通过引用传递test
作为@Nick建议,或者(不推荐)通过指针传递。只要{{1}}标记为虚拟
编辑:固定拼接 - &gt;切片..生化奇兵太多了..
答案 1 :(得分:2)
您需要更改参考(或指针)的参数
void pass(TestClass &t)
这样,将使用原始对象。
答案 2 :(得分:1)
如上所述,这是“切片”的结果。发生的具体细节如下:
当参数按值传递时,参数的副本将传递给函数。发生这种情况时,通过调用copy-constructor构造一个新对象。
对于您的示例,copy-constructor具有如下签名:
TestClass::TestClass(const TestClass&);
所以,真正发生的事情就像下面这样(再次,对于你的例子):
ExtendedTest et();
pass(et);
{ // entering scope of pass function ...
TestClass t = TestClass(t_orig); // inserted by the compiler
// evaluation of pass function ...
// ...
} // leaving scope of pass function, t is destroyed.
显然,由于变量t被实例化为TestClass,因此任何成员函数调用都来自TestClass(而不是ExtendedTest)。
最后请注意,在使用继承时,应始终声明虚拟析构函数。当对象被破坏时,这将避免切片。