如何调用孩子的方法:虚拟关键字不起作用

How can I make the method of child be called: virtual keyword not working?

本文关键字:方法 虚拟 关键字 不起作用 孩子 何调用 调用      更新时间:2023-10-16

这是我的代码,

#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')。但我希望调用 child 的方法,因为我将方法指定为虚函数。

那么如何调用子类的方法呢?谢谢。

void pass(TestClass t)
{
    t.test("abc","def");
}

执行此操作时,要传递的对象将被切成TestClass,并且其标识丢失,因此它现在的行为类似于TestClass并相应地调用该方法。

要解决此问题,您需要按照@Nick建议通过引用传递t,或者(不推荐)通过指针传递。它现在将保留其标识并调用相应的函数,只要test标记为虚拟

编辑:固定拼接->切片..太多的生物电击..

您需要更改引用(或指针)的参数

void pass(TestClass &t)

这样,将使用原始对象。

如上所述,这是"切片"的结果。 发生的情况的具体细节如下:

当参数按值传递时,参数的副本将传递给函数。发生这种情况时,通过调用复制构造函数构造一个新对象。

对于您的示例,复制构造函数具有如下签名:

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)。

最后,在使用继承时,应始终声明虚拟析构函数。 这将避免在销毁对象时切片。