复制分配方法中删除/重置成员的实用性

问题描述 投票:0回答:1
class B;

class A
{
 private:
   list<B*> myList;
   unique_ptr<B> smartUniq;
   

 public:
   A()
   {
      myList.push_back(new B(5));
      myList.push_back(new B(6));
      myList.push_back(new B(7));
   }

   ~A()
   {
      for (auto& item : myList)
      {
         
         delete item;
      }
      cout << "destructor"<<endl;
   }

   
   //Copy constructor
   A(const A &src)
   {
     for (auto& item : src.myList)
     {
       myList.push_back(new B(item->getb()));
     }
     smartUniq(make_unique<B>(*src.smartUniq))
   }
 
   /////////////////////////  VERSION1: Copy assignement  
   A& operator= (const A &src)
   {
     for (auto& item : myList)
     {
       if (item != nullptr)
          delete item;
     }
     
     for (auto& item : src.myList)
     {
       myList.push_back(new B(item->getb()));
     }
     smartUniq(make_unique<B>(*src.smartUniq))

     return *this;
   }

   /////////////////////////  VERSION2: Copy assignement  
   A& operator= (const A &src)
   {
     if( this != &src)
     {
         for (auto& item : src.myList)
         {
            myList.push_back(new B(item->getb()));
         }
         smartUniq.reset(src.smartUniq.get() ? make_unique<B>(*src.smartUniq) : nullptr);
     }

     return *this;
   }
};

Q1:哪个版本的副本分配是正确的(版本1或版本2或其他):

  • 复制前删除当前成员的实用程序是什么?
  • 有什么用处:
    if( this != &src)?

Q2:

smartUniq.reset
有什么用处:可以不像VERSION1那样使用吗?

c++
1个回答
0
投票

您的复制构造函数未正确初始化

unique_ptr

您的复制赋值运算符根本不应该重置

unique_ptr
,它应该直接复制
B
对象。

此外,您的 v1 复制赋值运算符在销毁其项目后不会清除

myList
,因此它会在其中留下悬空指针。而且你的 v2 操作员根本没有销毁这些物品。

此外,您还应该提供一个移动构造函数和一个移动赋值运算符。

试试这个:

class A
{
 private:
   list<B*> myList;
   unique_ptr<B> smartUniq;

 public:
   A()
   {
      myList.push_back(new B(5));
      myList.push_back(new B(6));
      myList.push_back(new B(7));
   }

   ~A()
   {
      for (auto item : myList)
      {
         delete item;
      }
      cout << "destructor" <<endl;
   }

   A(const A &src)
   {
     for (auto item : src.myList)
     {
       myList.push_back(new B(item->getb()));
     }
     smartUniq = make_unique<B>(*src.smartUniq);
   }

   A(A &&src)
   {
     myList = std::move(src.myList);
     smartUniq = std::move(src.smartUniq);
   }

   A& operator= (const A &src)
   {
     if (this != &src)
     {
         for (auto item : myList)
         {
             delete item;
         }
         myList.clear();

         for (auto item : src.myList)
         {
            myList.push_back(new B(item->getb()));
         }

         *smartUniq = *src.smartUniq;
     }

     return *this;
   }

   A& operator= (A &&src)
   {
     myList = std::move(src.myList);
     smartUniq = std::move(src.smartUniq);
     return *this;
   }
};
© www.soinside.com 2019 - 2024. All rights reserved.