Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C+编写副本构造函数和赋值运算符的检查表+; 请写一个复制构造函数和赋值操作符在C++中需要做的任务清单,以保持异常安全,避免内存泄漏等。 < P>我不知道安全例外,但我这样走。让我们假设它是一个模板化的数组包装器。希望有帮助:) 数组(常量数组和rhs) { mData=NULL; mSize=rhs.size(); *这=rhs; } 数组和运算符=(常量数组和rhs) { 如果(此==&rhs) { 归还*这个; } int len=rhs.size(); 删除[]mData; mData=新的T[len]; 对于(int i=0;i_C++_Copy Constructor_Assignment Operator - Fatal编程技术网

用C+编写副本构造函数和赋值运算符的检查表+; 请写一个复制构造函数和赋值操作符在C++中需要做的任务清单,以保持异常安全,避免内存泄漏等。 < P>我不知道安全例外,但我这样走。让我们假设它是一个模板化的数组包装器。希望有帮助:) 数组(常量数组和rhs) { mData=NULL; mSize=rhs.size(); *这=rhs; } 数组和运算符=(常量数组和rhs) { 如果(此==&rhs) { 归还*这个; } int len=rhs.size(); 删除[]mData; mData=新的T[len]; 对于(int i=0;i

用C+编写副本构造函数和赋值运算符的检查表+; 请写一个复制构造函数和赋值操作符在C++中需要做的任务清单,以保持异常安全,避免内存泄漏等。 < P>我不知道安全例外,但我这样走。让我们假设它是一个模板化的数组包装器。希望有帮助:) 数组(常量数组和rhs) { mData=NULL; mSize=rhs.size(); *这=rhs; } 数组和运算符=(常量数组和rhs) { 如果(此==&rhs) { 归还*这个; } int len=rhs.size(); 删除[]mData; mData=新的T[len]; 对于(int i=0;i,c++,copy-constructor,assignment-operator,C++,Copy Constructor,Assignment Operator,首先确保您确实需要支持复制。大多数情况下,情况并非如此,因此,禁用这两种功能是一条可行之路 有时,您仍然需要在多态层次结构的类上提供复制,在这种情况下:禁用赋值运算符,编写(受保护的?)复制构造函数,并提供虚拟克隆()函数 否则,如果您正在编写一个值类,那么您将回到Coplien的正交标准形式的领域。如果您有一个不能简单复制的成员,则需要提供复制构造函数、析构函数、赋值运算符和默认构造函数。此规则可以细化,例如,请参见: 我还建议您查看和。编译器生成的版本在大多数情况下都可以工作 当对象包含原始

首先确保您确实需要支持复制。大多数情况下,情况并非如此,因此,禁用这两种功能是一条可行之路

有时,您仍然需要在多态层次结构的类上提供复制,在这种情况下:禁用赋值运算符,编写(受保护的?)复制构造函数,并提供虚拟克隆()函数

否则,如果您正在编写一个值类,那么您将回到Coplien的正交标准形式的领域。如果您有一个不能简单复制的成员,则需要提供复制构造函数、析构函数、赋值运算符和默认构造函数。此规则可以细化,例如,请参见:


我还建议您查看和。

编译器生成的版本在大多数情况下都可以工作

当对象包含原始指针(不包含原始指针的参数)时,您需要更仔细地考虑这个问题。因此,您有一个原始指针,第二个问题是您是否拥有该指针(它是否被您删除)?如果是这样,那么您需要应用4的规则

拥有超过1个原始指针变得越来越难以正确操作(复杂性的增加也不是线性的[但这是观察性的,我没有真实的统计数据来支持这一说法])。因此,如果您有多个原始指针,请考虑将每个指针包装在其自己的类中(某种形式的智能指针)

第4条规则:如果对象是原始指针的所有者,则需要定义以下4个成员,以确保正确处理内存管理:

  • 建造师
  • 复制构造函数
  • 赋值运算符
  • 析构函数
如何定义这些将取决于具体情况。但要注意的是:

  • 默认构造:将指针设置为NULL
  • 复制构造函数:使用复制和交换ideum向“强异常保证”提供
  • 分配操作员:检查是否分配给自己
  • 析构函数:防止异常从析构函数传播出去
    • 试着读一下


      是一个非常好的赋值运算符分析

      此代码不是异常安全的。总是在发布前分配!不,不是。我对异常安全代码没有任何问题,所以我从来没有机会实践它。上面这个是ofc just snipper,通常使用STL容器。请发布你的代码片段,我想看一下。我在回复中提供的链接中有很多代码片段。顺便说一句,防止自分配的测试现在被视为反惯用语(现在,异常已被更好地理解)“顺便说一句,防止自分配的测试现在被视为反惯用语”链接到这个解释?我已经给出了我的另一个消息的链接——参见GOW和FAQ C++ Lite。我认为它被称为规则4.FAIK,它源自Jim Coplien的书,因此BTW的名称只适用于值类。有人称之为“四人法则”。还有关于(三)/C++ FAQ Lite(我找不到它)的解释/规则。多亏了RAII,它可以减少到两个。另外,还可以防止赋值运算符中的自赋值。@阿德里安:如果赋值运算符使用复制和交换,它就不需要进一步的保护。实际上,异常安全足以确保自赋值安全。复制和交换只是提供异常安全的一种简洁方式。“编译器生成的版本在大多数情况下都能工作。”-这取决于您所做的编程类型。即使一切都是智能指针,处理资源跟踪和异常问题,浅层副本在语义上可能不是您想要的。这通常是我在采访中会问的问题。然而,我看到了一个错误的假设:大多数OBJET要求是可复制的。“设计良好的C++系统中的每个对象都有默认构造函数、复制构造函数和赋值运算符”,这句话是基于值的对象,而不是实体。
      Array(const Array& rhs)
          {
              mData = NULL;
              mSize = rhs.size();
              *this = rhs;
          }
      
          Array& operator=(const Array& rhs)
          {
              if(this == &rhs)
              {
                  return *this;
              }
      
              int len = rhs.size();
      
              delete[] mData;
      
              mData = new T[len];
      
              for(int i = 0; i < len; ++i)
              {
                  mData[i] = rhs[i];
              }
      
              mSize = len;
      
              return *this;
          }