首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >协变返回类型和右值引用

协变返回类型和右值引用
EN

Stack Overflow用户
提问于 2021-05-22 21:59:30
回答 1查看 65关注 0票数 0

我的目标是在派生类上实现一个运算符,以便返回类型应该是派生类的类型。

我可以通过下面的代码来实现:

代码语言:javascript
复制
#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;的结果不做任何处理

EN

回答 1

Stack Overflow用户

发布于 2021-05-22 23:16:39

我看不到像@Eljay建议的那样,在不返回指针的情况下实现这一点的方法。返回引用是可行的,但我看不到任何方法可以确保调用者删除任何需要删除的内容。

我想到了这一点(其中func表示我将使用运算符的场景):

代码语言:javascript
复制
#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;
}

我会把这个问题放一段时间,以防有人找到更好的解决方案。否则,我会将其标记为答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67650329

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档