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

wco*_*ran 1 c++ reference

下面的参考变量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;
}
Run Code Online (Sandbox Code Playgroud)

如果我注释每个构造函数,我可以看到Bar在评估三元表达式时会调用该构造函数。如果我注释每个析构函数,我会看到Bar析构函数 foo初始化之前被调用-这告诉我Bar三元运算符创建了一个临时对象,但在初始化之前将其销毁了-为什么?

编译(Apple LLVM版本9.0.0(clang-900.0.39.2))

clang++ -Wall -std=c++11 foo.cpp -o foo
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 5

问题所在

const Foo& foo = condition ? Foo() : Bar();
Run Code Online (Sandbox Code Playgroud)

就是两个部分都需要返回相同的类型。由于Foo()Bar()不是同一类型,因此编译器会尝试将它们转换。它唯一可以做的有效转换就是将Bar()其切成薄片Foo。这意味着无论您得到什么,您都将对a的引用进行绑定,Foo并且该Bar零件消失。

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

#include <iostream>
#include <memory>

class Foo {
public:
    virtual ~Foo() = default;  // don't forget to add this when using polymorphism
    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;
    auto foo = condition ? std::make_unique<Foo>() : std::make_unique<Bar>();
    foo->say();   // outputs "Bar" now                                                                                                  
    return 0;
}
Run Code Online (Sandbox Code Playgroud)