c++ : move assignement operator and inheritance

夙愿已清 提交于 2021-02-11 14:17:12

问题


This code compiles and runs fine:

#include <iostream>

class Base
{
  public:
  Base(int value)
  : clean_(true)
  {
      value_ = new int;
      *value_ = value;
  }
  ~Base()
  {
      if(clean_)
        delete value_;
  }
  Base(Base&& other) noexcept 
  : value_{std::move(other.value_)},
    clean_(true)
  {
      other.clean_=false;
  }
  Base& operator=(Base&& other) noexcept
  {
      value_ = std::move(other.value_);
      other.clean_=false;
      clean_=true;
  }
  void print()
  {
      std::cout << value_ << " : " << *value_ << std::endl;
  }
  
  int* value_;
  bool clean_;
    
};

class A : public Base 
{
  public:
  A(int v1, double v2) : Base(v1)
  {
      a_ = new double;
      *a_ = v2;
  }
  A(A&& other) noexcept
  : Base(std::forward<Base>(other)),
    a_(std::move(other.a_))
  {}
  A& operator=(A&& other) noexcept
  {
      // should not the move assignment operator
      // of Base be called instead ? 
      // If so: how ?
      this->value_ = std::move(other.value_);
      other.clean_=false;
      this->clean_=true;
      a_ = std::move(other.a_);
  }
  void print()
  {
      std::cout << this->value_ << " "
                << *(this->value_) << " "
                << a_ << " " << *a_ << std::endl;
  }

  double* a_;
  bool clean_;
    
};

A create_a(int v1,double v2)
{
    A a(v1,v2);
    return a;
}

int main()
{
    Base b1(20);
    b1.print();
    
    Base b2 = std::move(b1);
    b2.print();
    
    A a1(10,50.2);
    a1.print();
    
    A a2 = std::move(a1);
    a2.print();
    
    A a3 = create_a(1,2);
    a3.print();
}

A is a subclass of Base.

The code of the move assignment operator of A replicates the one of Base.

Is there a way to avoid this replication of code ?


回答1:


Change int* value_; to int value_; and double* a_; to double a_; and you no longer need to write any of the special member functions as the compiler provided defaults Just Work™

If you really need dynamic memory allocation, then use a RAII type like std::vector, std::unique_ptr, std::shared_ptr, ect. in its place since they are designed to be copied and or moved correctly.



来源:https://stackoverflow.com/questions/63598109/c-move-assignement-operator-and-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!