使用解除引用对象调用虚函数

Par*_*eep 6 c++ inheritance

我有一个指向派生类对象的基类指针.我foo()在下面的代码中使用两种不同的方式调用函数.为什么Derived::foo()在第一种情况下被调用?不应该(*obj).foo()调用Base::foo()函数,因为它已被解除引用?

    class Base
    {
    public:
        Base() {}
        virtual void foo() { std::cout << "Base::foo() called" << std::endl; }
        virtual ~Base() {};
    };

    class Derived: public Base
    {
    public:
        Derived() : Base() {}
        virtual void foo() {  std::cout << "Derived::foo() called" << std::endl; }
        virtual ~Derived() {};
    };

    int main() {
        Base* obj = new Derived();
   // SCENARIO 1
        (*obj).foo();
// SCENARIO 2
        Base obj1 = *obj;
        obj1.foo();

        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

sbi*_*sbi 16

// SCENARIO 1
(*obj).foo();
Run Code Online (Sandbox Code Playgroud)

注意

  1. obj这里用词不当,因为它不是指对象,而是指针,
  2. (*ptr).foo()只是一个迂回的方式ptr->foo().

*ptr不会导致对象,而是对对象的引用 Base&.并且通过引用调用的虚函数受动态调度的影响,就像通过指针调用一样.

// SCENARIO 2
Base obj1 = *ptr;
obj1.foo();
Run Code Online (Sandbox Code Playgroud)

你在这里做的是通过切片创建一个全新的对象:它只有基类部分*ptr.你想要的是这样的:

Base& ref = *ptr;
ref.foo();
Run Code Online (Sandbox Code Playgroud)