对象切片是否依赖于构造函数的实现?

Is object slicing dependent on the constructor implementation?

在尝试对象切片和多态性的概念时,我想出了这个代码示例,它按我的预期工作:派生的 FunctorTrue class 的函数调用运算符被调用- 而不是父 Functor class.

#include <iostream>
#include <functional>
using namespace std;

class Functor : public std::function<bool()> {
public:
virtual ~Functor() {};
    virtual bool operator()() const {return false;};
};

class FunctorTrue : public Functor{
public:
    bool operator()() const {return true;}
};

class Dispatcher {
public:
    const Functor & mFunctor; 
    Dispatcher(const Functor & functor): mFunctor(functor) {}
    Dispatcher(const Functor && functor): mFunctor(functor) {
    }

    void dispatch(){
        cout << boolalpha << mFunctor() << endl;
    }
};

int main() {
    Dispatcher dt = Dispatcher(FunctorTrue());
    dt.dispatch(); // returns true
}

注意:您可以run this example in Ideone

我发现如果我修改 Dispatcher class 的构造函数来打印一行,则会调用父函数调用运算符:

class Dispatcher {
public:
    const Functor & mFunctor; 
    Dispatcher(const Functor & functor): mFunctor(functor) {}
    Dispatcher(const Functor && functor): mFunctor(functor) {
        cout << "Constructor with rvalue" << endl;
    }

    void dispatch(){
        cout << boolalpha << mFunctor() << endl;
    }
};

int main() {
    Dispatcher dt = Dispatcher(FunctorTrue());
    dt.dispatch(); // returns false
}

注意:您可以also run this example in Ideone

那个意想不到的行为让我想到,由于 Dispatcher class 中的成员变量 mFunctor 的类型,dispatch 方法只知道对象的"base class part",有效调用基class的函数调用操作符。但这在原始示例中并不成立,这让我很困惑。

我的问题是:

1) 为什么构造函数中的更改会更改 Functor > FunctorTrue class 层次结构中调用的方法?

2) 如果变化与默认构造函数所做的某些优化有关,那么该优化是什么,我该如何指定它?

非常感谢。

您有未定义的行为。

您的构造函数正在存储对生命周期结束的对象的引用,然后 dispatch() 尝试使用该对象。

int main() {
    Dispatcher dt = Dispatcher(FunctorTrue());
       // lifetime of FunctorTrue object ends here

    dt.dispatch(); // Use of dt.mFunctor causes undefined behavior
}