问题标签 [rule-of-three]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
620 浏览

c++ - 是否有任何静态分析工具可以检查规则 3(或规则 5 C++11)

我目前正在开发一个建立在沙子基础上的代码库。

据称经过测试的库中有许多违反“3 规则”的类。大多数声明了一个重要的析构函数,但缺少复制构造函数或赋值运算符。

是否有任何编译器标志 (gcc) 或静态分析工具会在类违反规则 3 时发出警告?

目前我们正在使用 GCC 版本 4.4 的 Coverity。

0 投票
1 回答
1044 浏览

c++ - C ++:复制和交换习语,替代构造函数

注意:这个问题是在上一个问题之后,我希望仍然可以将它作为一个新问题提出。

我正在尝试为树类实现“三个半大规则”(复制和交换习语),如下所示:

我一直在努力遵循这个准则。这是我的复制赋值运算符的样子:

我很难让我的公共构造函数工作。有人建议我这样做:

我不确定这个想法是否有效。在任何情况下,我都会从编译器收到以下错误:

我尝试了以下想法,我认为它会起作用:

但它似乎也不起作用。我认为问题在于,当我调用复制赋值运算符 ( *this = Tree(&aTemp, &bTemp, depth, depth)) 时,应该调用复制构造函数(因为复制赋值运算符的参数是按值传递的),但似乎没有发生这种情况。我不懂为什么。

提前感谢您的帮助!

0 投票
1 回答
122 浏览

c++ - 类成员在复制构造或通过分配复制后出现乱码(有时)

我的班级NRRanNormal代表一个正态分布的随机变量。默认情况下,实例正态分布,均值为 0,标准偏差为 1(即标准正态随机变量)。

有时当我复制NRRanNormal对象时,复制到(或通过复制构造函数构造)的对象的均值和标准差是乱码和胡说八道。我很难找到这种乱码的原因。

NRRanNormal出于测试目的,以下函数显示给定对象的均值和标准差:

现在,让我们看看以下 4 种情况会发生什么:

上述语句的输出如下:

如您所见,只需实例化一个对象 ( foo) 即可按预期工作。

现在,当我这样做时NRRanNormal bar1 = foo;,对象bar1是乱码。但是,当我这样做时,NRRanNormal bar2; bar2 = foo;对象不会乱码。这让我很困惑。我认为一个语句块如bar2

实际上是由编译器转换为语句块

因此,除非我刚刚在上面写的内容不正确,否则似乎bar1并且bar2应该具有完全相同的成员值。但正如您从上面粘贴的输出中看到的那样,bar1是乱码,而bar2很好。

怎么会这样?

您还会注意到这bar3是乱码。我不确定这是同一个问题,还是另一个问题。


这是接口和实现的简化版本NRRanNormal

Normaldev结构来自 Numerical Recipes 3d Edition。

我的复制赋值运算符或复制构造函数有问题吗?


这是Normaldev,剥离了专有计算。

0 投票
2 回答
57 浏览

c++ - 传递一个包含动态内存的类:方法及其效率

我有一个包含大量数据的类,称为HeavyData. 此类遵循三规则(它重写了复制构造函数、复制赋值运算符和析构函数,以便someBigAmountOfData 在复制类时能够正确复制成员变量并能够释放类而不会导致内存泄漏)。

该类DataManager有两个类型的成员变量HeavyData。(见下文)

问题 :

该类DataManager有两个构造函数,如下所示:

  1. DataManager(HeavyData one, HeavyData two); //方法一

  2. DataManager(const HeavyData& one, const HeavyData& two); //方法二

问题在于从上述两个中选择一个构造函数。你觉得哪一个更有效率?为什么?

认为第二个构造函数(方法2)更有效。

0 投票
2 回答
745 浏览

c++ - C++ - 对于指向对象的指针向量,重新分配是否会导致对象的删除和复制?

根据我目前的理解,如果你有一个类对象的向量,如果你删除了向量的任何成员,通常向量会重新分配它的一些对象以保持内存连续性。因此,您需要实现三个规则(析构函数、复制构造函数和复制赋值运算符),以便在擦除向量成员时保留所有内容。

但是:对于指向类对象的指针向量,结果对我来说不太清楚。如果我删除一个成员,那么 C++ 肯定足够聪明,可以只复制指针 - 而不是疯狂地删除指针(及其指向的类对象)然后重新创建它并再次指向它?

如果不是这样,有人可以向我解释这个白痴吗?

0 投票
2 回答
2544 浏览

c++ - 如果类包含用户声明的析构函数,那么复制构造函数会怎样?

第 12.8/7 节中的标准说:

如果类定义没有显式声明复制构造函数,则隐式声明。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数定义为已删除;否则,它被定义为默认值(8.4)。如果 类具有用户声明的复制赋值运算符或用户声明的 析构函数,则不推荐使用后一种情况。因此,对于类定义

复制构造函数是隐式声明的。如果用户声明的构造函数后来被定义为

我不明白如果该类具有用户声明的复制赋值运算符或用户声明的析构函数,则不推荐使用后一种情况。在示例中,标准既不提供用户声明的复制赋值运算符也不提供析构函数。如果我们声明析构函数或复制赋值运算符会发生什么?我试图这样做如下:

演示

但在示例中,我们仍然有隐式声明的复制构造函数。该规则的实际含义是什么?

我想如果我们写以下内容:

演示

复制构造函数不会显式删除。但事实并非如此。

0 投票
2 回答
105 浏览

c++ - 分段故障; 三法则

我有一个这样的头文件

然后在我的 .cpp 文件中写下这一行

这是给分段错误。我想这是由于三规则。然后我添加了这部分;复制构造函数和赋值构造函数

还是行不通。请任何人帮我解决这个问题。谢谢

0 投票
1 回答
2024 浏览

c++ - 动态多维数组错误的C++重载赋值运算符

我在用动态数组重载 = 运算符时遇到了麻烦。这就是我到目前为止所拥有的。另外我知道我还没有写我的析构函数或构造函数,但我需要首先关注这个运算符:

在我的头文件中:

0 投票
2 回答
69 浏览

c++ - 未分配内存指针中的三个大泄漏的 C++ 错误(不重复)

我的代码运行不正确,我不知道如何修复它。对于询问什么是三规则的人来说,这不是一个重复的问题,因为那篇文章并不能帮助我解决我的问题,就像在这篇文章中我使用指针指针数组一样。我不知道我在三大功能中做错了什么,但有人可以帮我纠正我的错误。编译器突出显示 delete[] matrix[i]; 在 for 循环内 i=2 时的析构函数中

在我的头文件中,我有:

0 投票
2 回答
195 浏览

c++ - 三法则运动出乎意料的结果

我尝试在空闲时间学习 C++ 基础并遵循一本书的练习。首先,当我输入 9 作为行和 8 作为列时,我得到 malloc freeing 错误。其次,我得到 0 作为输出,我看不到我输入的内容。我想编写程序,因为我可以加强三法则。这当然不是家庭作业。此外,我认为这是一个困难的问题和有效的问题。如果可以回答问题,那将很有帮助。因为我在谷歌上搜索过,所以我找不到关于解决方案的一半体面的东西。另外,你能检查我的复制构造函数、赋值运算符和析构函数并告诉我我的错误在哪里吗?

编写一个类 TwoD,它在其构造函数中使用此显示的想法来实现二维动态双精度数组。您应该有一个指向 double 类型的私有成员以指向动态数组,以及两个 int(或无符号 int)值,它们是 MaxRows 和 MaxCols。您应该提供一个默认构造函数,您将为其选择默认的最大行和列大小,以及一个允许程序员设置最大行和列大小的参数化构造函数。此外,您应该提供一个允许设置特定行和列条目的 void 成员函数,以及一个将特定行和列条目作为 double 类型的值返回的成员函数。备注:重载 [ ] 很困难或不可能(取决于细节),因此它可以像您希望的那样用于二维数组。因此,只需使用普通函数表示法来使用访问器和修改器函数。将 + 运算符重载为友元函数以添加两个二维数组。此函数应返回 TwoD 对象,其第 i 行第 j 列元素是左侧操作数 TwoD 对象的第 i 行第 j 列元素与右侧操作数 TwoD 对象的第 i 行第 j 列元素之和。提供一个复制构造函数、一个重载的运算符 = 和一个析构函数。将不更改数据的类成员函数声明为 const 成员。左侧操作数 TwoD 对象的第 j 列元素和右侧操作数 TwoD 对象的第 i 行第 j 列元素。提供一个复制构造函数、一个重载的运算符 = 和一个析构函数。将不更改数据的类成员函数声明为 const 成员。左侧操作数 TwoD 对象的第 j 列元素和右侧操作数 TwoD 对象的第 i 行第 j 列元素。提供一个复制构造函数、一个重载的运算符 = 和一个析构函数。将不更改数据的类成员函数声明为 const 成员。

我的努力