C++ 对象切片是否依赖于构造函数实现?
在尝试对象切片和多态性的概念时,我提出了这个代码示例,正如我所期望的那样:调用派生的C++ 对象切片是否依赖于构造函数实现?,c++,polymorphism,object-slicing,C++,Polymorphism,Object Slicing,在尝试对象切片和多态性的概念时,我提出了这个代码示例,正如我所期望的那样:调用派生的functorrue类的函数调用操作符,而不是父Functor类的函数调用操作符 #include <iostream> #include <functional> using namespace std; class Functor : public std::function<bool()> { public: virtual ~Functor() {}; vir
functorrue
类的函数调用操作符,而不是父Functor
类的函数调用操作符
#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
}
注意:你可以
这个意外的行为让我想到,由于Dispatcher
类中成员变量mFunctor
的类型,dispatch
方法只知道对象的“基类部分”,有效地调用基类的函数调用操作符。但这在最初的例子中并不成立,这让我很困惑
我的问题是:
1) 为什么构造函数中的更改会更改在Functor>functorrue
类层次结构中调用的方法
2) 如果变体与默认构造函数所做的某些优化相关,那么该优化是什么,我如何指定它
事先非常感谢。您有未定义的行为 构造函数正在存储对生命周期结束的对象的引用,然后
dispatch()
尝试使用该对象
int main() {
Dispatcher dt = Dispatcher(FunctorTrue());
// lifetime of FunctorTrue object ends here
dt.dispatch(); // Use of dt.mFunctor causes undefined behavior
}
谢谢这很可能是我第一次遇到类似的事情,或者是第一次有人指出这是问题的根本原因。未定义的行为并不是我通常将其放在脑后作为bug的可能原因。你的回答鼓励我改变这一点^^^等一下。。。
Dispatcher
类的mFunctor
成员的常量如何不延长该functorrue()
temporary的生命期?@levelont:临时生命期不会间接延长。从主体的角度来思考。它怎么知道(通常)构造函数将保留一个引用呢?但是。。。编译器没有执行变量生命扩展,它可以“窥视”所有代码的实现,并看到在封皮后面,有一个常量引用可以延长临时变量的生命?@levelont:没有。临时变量绑定到functor
参数,该参数是一个引用。这会导致临时表达式一直存在到完整表达式的结束。将函子
(它是引用,而不是临时)绑定到mFunctor
的事实不会改变这一点。
int main() {
Dispatcher dt = Dispatcher(FunctorTrue());
// lifetime of FunctorTrue object ends here
dt.dispatch(); // Use of dt.mFunctor causes undefined behavior
}