如何根据条件使用不同的构造函数初始化C ++参考?

时间:2019-03-28 14:16:27

标签: c++ reference

下面的引用变量fooFoo的实例或其基于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

1 个答案:

答案 0 :(得分:5)

问题

localhost

是两个部分都需要返回相同的类型。由于const Foo& foo = condition ? Foo() : Bar(); Foo()的类型不同,因此编译器将尝试对其进行转换。它唯一可以做的有效转换就是将Bar()切成其{​​{1}}部分。这意味着无论您得到什么,都将绑定对Bar()的引用,而Foo部分将消失。

要解决此问题,您需要使用类似

的指针
Foo