下面的引用变量foo
用Foo
的实例或其基于Bar
的派生类condition
初始化。奇怪的是,基于say()
方法的输出,foo
似乎是Foo
的实例,而不是Bar
的实例-为什么?
#include <iostream>
class Foo {
public:
virtual void say() const {
std::cout << "Foo\n";
}
};
class Bar : public Foo {
public:
virtual void say() const {
std::cout << "Bar\n";
}
};
int main() {
constexpr bool condition = false;
const Foo& foo = condition ? Foo() : Bar();
foo.say(); // outputs "Foo” ???
return 0;
}
如果我注释每个构造函数,我可以看到在评估三元表达式时会调用Bar
构造函数。如果我注释每个析构函数,我会看到Bar
析构函数在 初始化之前被调用foo
—这告诉我三元运算符创建了一个临时Bar
对象,但是在初始化之前被销毁了-为什么?
编译为(Apple LLVM版本9.0.0(clang-900.0.39.2))
clang++ -Wall -std=c++11 foo.cpp -o foo
答案 0 :(得分:5)
问题
localhost
是两个部分都需要返回相同的类型。由于const Foo& foo = condition ? Foo() : Bar();
和Foo()
的类型不同,因此编译器将尝试对其进行转换。它唯一可以做的有效转换就是将Bar()
切成其{{1}}部分。这意味着无论您得到什么,都将绑定对Bar()
的引用,而Foo
部分将消失。
要解决此问题,您需要使用类似
的指针Foo