class Base
{
public:
void operator()() { func(); }
private:
virtual void func() {}
};
class Derived1 : public Base
{
private:
void func() override {/*do something*/}
};
class Derived2 : public Base
{
private:
void func() override {/*do something else*/}
};
因为我想使用运算符重载,所以 参考是比指针更好的选择。
我打算做的是:
if (condition) {
Base& obj = Derived1();
} else {
Base& obj = Derived2();
}
但是obj将被销毁并且范围结束。
Base& obj;
if (condition) {
obj = Derived1();
} else {
obj = Derived2();
}
也不会工作,
因为引用需要在声明时初始化。
如果我尝试:
Base& obj = condition ?
Derived1() : Derived2();
仍然是错误, 因为三元运算符期望可转换类型。
解决这个问题的最佳解决方案是什么?
答案 0 :(得分:5)
在这种情况下,您无法使用?:
,因为Derived1和Derived2是不同类型。
一种可能的方法是使用指针,这是有效的:
condition ? pObj.reset(new Derived1()) : pObj.reset(new Derived2());
或者
#include <memory>
std::unique_ptr<Base> pObj;
if (condition)
{
pObj.reset(new Derived1());
}
else
{
pObj.reset(new Derived2());
}
您可以通过这种方式拨打operator()
:
(*pObj)();
答案 1 :(得分:1)
您可以修改以下代码
Base *obj1;
if (condition) {
obj1 = new Derived1();
} else {
obj1 = new Derived2();
}
Base &obj = *obj1;
但请确保稍后删除obj1
答案 2 :(得分:1)
如果您想要引用,除非是const Base &
,否则不能将临时绑定到它。这意味着你需要一个实际的对象来绑定,所以让我们从那开始:
Derived1 d1;
Derived2 d2;
但是,您可以使用函数(包括lambda)获取非const引用。如果lambdas不可用,则需要使用d1
和d2
作为参数的正常函数。
auto choose = [&](bool b) -> Base & {
if (b) {return d1;}
else {return d2;}
};
现在创建obj
非常简单:
Base &obj = choose(condition);
答案 3 :(得分:0)
这样可行:
Base* obj;
if (condition) {
obj = new Derived1;
} else {
obj = new Derived2;
}
然后在代码的末尾添加
delete obj