问题标签 [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 投票
1 回答
208 浏览

c++ - 在 QVector 插入函数后无法访问的点

我正在尝试遵循三规则,但是这样做会导致 QVector 的插入功能出现问题。

添加复制构造函数和析构函数后,我的程序将产生一个错误,其中点向量不再可访问,因此复制构造函数无法重新分配点。

这是我的代码中的一些片段

现在,我使用使用 QVector 函数的 qSort 按面积对一组“形状”对象进行排序。

当此方法完成时。我发现其中一个形状现在有一个值为 的 mList <not accessible>。仅当使用 QVector::insert(int i, const T &value) 时才会在排序中出现。


到目前为止,此形状列表已被编辑和操作,但这是迄今为止唯一一次无法访问形状列表。原因是什么,我应该如何解决这个问题?

0 投票
1 回答
46 浏览

c++ - 使 2 个非静态字段(即动态数组)彼此靠近使用内存

B1B2成为一个动态大小的存储类。
(例如B1~std::vector<char> B2~std::vector<float>

在 C++11 中,如果我编写B1andB2和函数(五规则),包含它们作为字段的类move将默认自动正确复制/移动。copyC

它工作得很好。

问题

今天,我得到了配置文件结果+做了一些关于性能问题的测试。
主要目标:我必须在彼此附近创建相同的分配内存b1实例b2: -C

如果可以的话,我会让整个程序的性能提升 10-20%。

我的糟糕解决方案

我可以使用这样的自定义分配器(伪代码):-

它可以工作,但代码变得更难调试/维护。更不用说C移动和复制了。

在旧版本中, all copy/ movemess 只出现在B1and中B2
现在,混乱出现在每个直接使用数据结构的类B1B2

问题

什么是可以提供帮助的 C++ 技术/设计模式/习语?
要回答,不需要可运行的代码。伪代码或只是一个概念就足够了。

我很遗憾没有提供 MCVE。
自定义分配器和数组管理是非常难以最小化的事情。

0 投票
1 回答
2200 浏览

c++ - 五规则和隐式删除函数

就我的理解而言,五法则是指导性规则。尽管如此,我已经看到编译器在某些情况下可能会隐式删除函数。例如,在定义 move-ctor' 时,将删除复制分配/复制 ctor'。

我想知道是否还有上述情况。也就是说,用户自定义函数在哪些场景下可以隐式删除其他函数?

谢谢

编辑:
引用一些涵盖该主题的来源也可以!

0 投票
0 回答
63 浏览

c++ - 规则 5 - 编译时不使用赋值运算符

为了在处理数组成员时理解移动运算符,我编写了以下开发测试。

当我通过不实现赋值或移动赋值运算符而违反了 5 规则时,为什么这会起作用和/或编译?

我目前正在使用 Visual Studio 2015。

0 投票
1 回答
206 浏览

c++ - 具有结构的类中的析构函数问题

我目前在为我的Model班级编写/使用析构函数时遇到问题。对于 OpenGL 分配,我必须编写一个数据结构来保存有关模型的所有信息,请参阅Model.h下面的实现。此类包含指向各种结构的指针,并且我已经学会了在堆上分配内存后正确清理。

目前,我的应用程序在我的析构函数被注释掉时运行良好,但这确实给我带来了内存泄漏,我很确定我的讲师会因此给我一个显着较低的分数。

但是,在定义(取消注释)我的析构函数时,我遇到了问题。在运行一个调用的方法InitModels(见下面的实现)之后,我的析构函数被调用,它抛出了一个应用程序中断异常:

析构期间抛出异常

我在这里想念什么?我听说过并阅读了一些可能与我的问题有关的关于三规则的内容,但我被困在从哪里开始在我的案例中应用此规则。

这是我的InitModels方法:

这是我的Model.h

0 投票
3 回答
3134 浏览

c++ - c++ 接口必须遵守五法则吗?

定义接口类时声明实例化方法的正确方法是什么?

出于显而易见的原因,抽象基类必须具有虚拟析构函数。但是,随后给出以下编译警告:“'InterfaceClass' 定义了非默认析构函数但未定义复制构造函数、复制赋值运算符、移动构造函数或移动赋值运算符”,这是“五规则” '。

我理解为什么一般应该遵守“五法则”,但它仍然适用于抽象基类或接口吗?

我的暗示是:

这个对吗?这些方法应该= delete取而代之吗?是否有某种方法可以将析构函数声明为虚拟纯,同时又以某种方式保持默认?

即使我将析构函数声明为: virtual ~InterfaceClass() = default;,如果我没有明确默认其他四个,那么我将得到相同的编译器警告。

Tl; dr:当用户必须定义​​一个虚拟析构函数时,满足接口类“五规则”的正确方法是什么。

感谢您的时间和帮助!

0 投票
2 回答
1561 浏览

c++ - C++ 抽象类是否需要遵守五法则?

当实现这样的抽象类时:

这个接口是否必须遵守五规则,即我是否必须添加复制构造函数、复制赋值运算符、移动构造函数和移动赋值运算符?

我认为Base由于纯虚成员函数而无法实例化类型的实例,因此为其他特殊成员函数提供默认实现可能没有实际用途。

是否有任何用例/示例需要我提供其他特殊成员函数?

0 投票
1 回答
53 浏览

c++ - 堆栈变量和函数的 C++ 奇怪行为

我有一个String带有 achar* buffer和 a的课程unsigned int length

string 类有两个构造函数:

和一个析构函数

删除 char 数组delete[] buffer;

两个构造函数都创建一个新的缓冲区数组,并用来自或buffer = new char[size];的正确数据填充它。字符串缓冲区以空值结尾。const char* stringconst String& other

在我的主要功能中,我有以下代码:

我希望它能够打印Heppo到控制台。该replace函数采用两个字符,其中第一个字符的所有出现都被第二个字符替换。它返回一个全新的String

据我了解,编译器将返回局部变量的副本s。因此,a变量 inmain()应该是完全合法的String. 但是控制台的输出看起来像¦¦¦¦¦¦¦¦¦¦,看起来像未初始化的内存。

更奇怪的是,当我将主要方法更改为:

我看到了预期的输出。经过大量阅读后,我无法找到解决方案,因为在 google/stackoverflow 搜索中很难描述这个问题。

0 投票
2 回答
954 浏览

c++ - 复制构造函数中的递归调用

我按照三规则实现了一个类,但我遇到了崩溃。经过调试,我得出的结论是复制构造函数重复调用自身而不是调用相等运算符。为什么会这样?它不应该调用相等运算符吗?

0 投票
1 回答
80 浏览

c++ - 不在复制分配运算符中检查对象是否分配给自身真的安全吗?

这是我发现的实现“三法则”的示例:

正如您在上面看到的,复制赋值运算符中的检查被删除,因为创建局部变量然后删除成员指针并将其分配给局部变量。但是,如果我写,我最重要的是:

我分配a1给自己这是否意味着a1'vals被删除,然后a在复制分配运算符中分配了本地?这是正确的方法吗?我的代码有一些陷阱吗?

  • 任何提示,建议都非常感谢。