我的目标是在派生类上实现一个运算符,以便返回类型应该是派生类的类型。
我可以通过下面的代码来实现:
#include <iostream>
class Base{
public:
virtual Base&& operator+ (const Base &b) = 0;
virtual void Val() = 0;
};
class Derived : public Base{
public:
Derived&& operator+ (const Base &b) override
{
Derived *res = new Derived;
auto tmp = dynamic_cast<const Derived*>(&b);
if(tmp) res->fVal = this->fVal+tmp->fVal;
return std::move(*res);
}
void SetVal(double val){fVal = val;}
void Val() override{std::cout<<"derived:"<<fVal<<std::endl;}
private:
double fVal{0};
};
int main(){
Derived a;
a.SetVal(2);
Derived b;
b.SetVal(3);
Base *baseptr = new Derived(a+b);
baseptr->Val();
Base &&d = a+b;
d.Val();
Derived e = dynamic_cast<Derived&>(d);
e.Val();
return 0;
}我真的不喜欢使用rvalue-reference作为返回类型,所以我想知道是否有一个更简单的解决方案,我看不到。返回派生类型的副本不起作用,因为gcc声明返回类型不是协变的。
编辑:正如@ofo所提到的,我可以实现与返回左值引用非常相似的结果。目前,它是最适合我的选择。然而,(至少可以说)等待发生内存泄漏仍然是不可取的,我只需要对a+b;的结果不做任何处理
发布于 2021-05-22 23:16:39
我看不到像@Eljay建议的那样,在不返回指针的情况下实现这一点的方法。返回引用是可行的,但我看不到任何方法可以确保调用者删除任何需要删除的内容。
我想到了这一点(其中func表示我将使用运算符的场景):
#include <iostream>
#include <memory>
class Base{
public:
virtual std::unique_ptr<Base> operator+(const Base &) = 0;
virtual void SetVal(double) = 0;
virtual void Val() = 0;
};
class Derived : public Base{
public:
std::unique_ptr<Base> operator+(const Base &b) override
{
std::unique_ptr<Base> res = std::make_unique<Derived>();
auto tmp = dynamic_cast<const Derived*>(&b);
if(tmp) res->SetVal(this->fVal+tmp->fVal);
else std::cout<<"now i deal with invalid type case"<<std::endl;
return res;
}
void SetVal(double val) override{fVal = val;}
void Val(){std::cout<<fVal<<std::endl;}
private:
double fVal{0};
};
void func(Base &a, Base &b)
{
auto res = a+b;
res->Val();
}
int main(){
Derived a;
a.SetVal(2);
Derived b;
b.SetVal(3);
auto d = a+b;
d->Val();
func(a,b);
return 0;
}我会把这个问题放一段时间,以防有人找到更好的解决方案。否则,我会将其标记为答案。
https://stackoverflow.com/questions/67650329
复制相似问题