对象切片是否依赖于构造函数的实现?
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
}
在尝试对象切片和多态性的概念时,我想出了这个代码示例,它按我的预期工作:派生的 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
}