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

后端 未结 3 1917
天命终不由人
天命终不由人 2021-01-20 12:22

The following is my code,

#include
#include

using namespace std;

class TestClass
{
  public:
    virtual void test(string st1         


        
相关标签:
3条回答
  • 2021-01-20 12:47
    void pass(TestClass t)
    {
        t.test("abc","def");
    }
    

    When you do this, the object you are passing gets sliced into a TestClass and its identity is lost, so it now behaves like a TestClass and calls the method accordingly.

    To Fix this you want to pass t by reference as @Nick suggested, or (not recommended) by pointer. It will now retain its identity and call the appropriate function, as long as test is marked virtual

    Edit: fixed spliced -> sliced .. too much bioshock..

    0 讨论(0)
  • 2021-01-20 12:48

    As noted above, this is a result of "slicing". The specific details of what occurs is as follows:

    When arguments are passed by value, a copy of the argument is passed to the function. When this happens, a new object is constructed by calling the copy-constructor.

    For your example, the copy-constructor has a signature as follows:

    TestClass::TestClass(const TestClass&);
    

    so, what really happens is something like the following (again, for your example):

    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.
    

    Obviously, since the variable t is instantiated as a TestClass, any member function calls will be from TestClass (and not ExtendedTest).

    As a final note, you should always declare virtual destructors when using inheritance. This will avoid slicing when objects are destroyed.

    0 讨论(0)
  • 2021-01-20 12:58

    You need to change the parameter for a reference (or a pointer)

    void pass(TestClass &t)
    

    This way, the original object will be used.

    0 讨论(0)
提交回复
热议问题