就我的理解,五法则是指导性法则。尽管如此,我已经看到编译器在某些情况下可能会隐式删除函数。例如,当定义一个 move-ctor' 时,复制分配/复制 ctor' 将被删除。
我想知道是否有提到的更多场景。换句话说,自定义函数在哪些场景下可以隐式删除其他函数?
谢谢
编辑:
参考一些涵盖该主题的来源也可以!
以下代码片段是否泄漏?如果没有,那么在foobar()中构造的两个对象在哪里被破坏?
class B
{
int* mpI;
public:
B() { mpI = new int; }
~B() { delete mpI; }
};
void foobar()
{
B b;
b = B(); // causes construction
b = B(); // causes construction
}
Run Code Online (Sandbox Code Playgroud) 我最近读过,三条规则,我想知道我是否违反了它?
在我的GUI应用程序,类,如MainFrame,Interface,Circuit,Breadboard等(类名指示)有他们每个人的单个实例.在他们的构造函数中,我已经分配了一些资源(内存),我在析构函数中安全地释放了这些资源.
所以我只定义了析构函数,但没有定义复制构造函数和赋值运算符.
我确信我不需要它们,但我很好奇我是否违反了规则,我可以/应该做些什么来遵循它?
我读过三法则,三法则是什么?总结如下:
如果您需要自己显式声明析构函数,复制构造函数或复制赋值运算符,则可能需要显式声明它们中的所有三个.
我的问题是:在C++应用程序中,我有一个管理资源的类(有一个处理删除指针的析构函数).我知道应用程序在所有地方使用赋值运算符,但我绝对肯定在复制构造函数的应用程序中没有用法,即Class c(..); Class d(c);在这些情况下使用类型,我仍然需要同时实现赋值运算符和复制构造函数?或者一个赋值算子是否足够?赋值运算符是否可能以某种方式使用复制构造函数?
欣赏你的想法.
我写了一个测试来检查在堆栈变量上覆盖赋值之前是否调用了析构函数,我找不到结果的任何合理解释......
这是我的测试(在Visual C++ 2008发布模式下):
#include <iostream>
class C {
public:
char* ptr;
C(char p) { ptr = new char[100]; ptr[0] = p;}
~C() { std::cout << ptr[0] << ' '; delete [] ptr; }
};
int _tmain(int argc, _TCHAR* argv[])
{
{
C s('a');
s = C('b');
s = C('c');
s = C('d');
}
std::cin.get();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我的假设是真的,我期望得到"abcd",如果是假的话,我只是"d".相反,我得到"bcdx"."x"的变化取决于分配给ptr的内存量,表明它正在读取随机堆值.
我相信正在发生的事情(如果我错了,请纠正我)是每个构造函数调用都会创建一个新的堆栈值(让我们称之为s1,s2,s3,s4),然后这些赋值会让s1.ptr被s4.ptr覆盖. .然后在复制之后立即销毁s4,但是在离开作用域时s1(带有悬空ptr)被销毁,导致s4.ptr的双重删除并且没有删除原始的s1.ptr.
有没有办法解决这个无用的行为,不涉及使用shared_ptrs?
编辑:用'delete []'替换'delete'
关于这个主题:什么是复制和交换习惯用法?
它声明一个类最多应该处理一个资源.资源是什么意思?
编辑:例如,我有一个类来处理每个监视器的信息,并包含一个桌面像素数组.数组和只有数组会被视为资源吗?保持监视器信息和桌面数组的监视器数组是否会是另一个资源,需要另一个类?这是在另一个班级,但这是什么意思?
我在这里和谷歌搜索过,但只找到有关三个规则或资源文件(*.rc和MSDN)的更多信息.没有任何与定义有关的东西.
三规则(也称为三巨头或三巨头的规则)是C++中的经验法则,它声称如果一个类定义了下面的一个,它应该明确地定义所有三个:析构函数,复制构造函数,复制赋值运算符.
为什么非默认构造函数不被视为其中之一?当在类中管理任何资源时,程序员必须始终定义非默认构造函数.
我正在编写一个C++应用程序,其中我有一个Controller带有两个嵌套结构的类,在我的头文件中定义如下:
class Controller {
struct help_message { // controller.hpp, line 19
std::string summary;
std::string details;
help_message(const std::string&, const std::string&);
};
struct player_command {
cmd_t cmd;
help_message help;
// cmd_t is my own typedef, irrelevant for this question
player_command(const cmd_t&, const help_message&);
};
// more members...
};
Run Code Online (Sandbox Code Playgroud)
在我的源文件中,我有这个:
Controller::player_command::player_command(const Controller::cmd_t& c, const help_message& h) {
cmd = c;
help = h;
};
Controller::help_message::help_message(const std::string& s, const std::string& d) {
summary = s;
details = d;
};
Run Code Online (Sandbox Code Playgroud)
我觉得很好,但是当我编译时,这就是我得到的(controller.cpp第12行是上面源代码片段的第一行):
g++ -g …Run Code Online (Sandbox Code Playgroud) 这是一个实现"三个规则"的例子,我发现:
class Array {
public:
int size;
int* vals;
Array() : size(0), vals(NULL){}
Array( int s, int* v );
Array(const Array&); // 1
Array& operator=(const Array&); // 2
~Array(); // 3
};
Array::~Array() {
delete []vals;
vals = NULL;
}
Array::Array( int s, int* v ){
size = s;
vals = new int[size];
std::copy( v, v + size, vals );
}
Array::Array(const Array& rhs):
size(rhs.size),
vals((rhs.size) ? new int[size] : NULL)
{
if(size)
std::copy(rhs.vals, rhs.vals + rhs.size, vals);
}
Array& …Run Code Online (Sandbox Code Playgroud) 我对此有疑问:
class A
{
int a;
int* pa;
public:
A(int i):a(i) , pa(new int(a))
{
cout<<"A ctor"<<a<<endl;
}
~A()
{
delete pa;
cout<<"dtor\n";
}
int * &get()
{
return pa;
}
};
class B : public A
{
int b;
public:
B (A obj): A(obj) , b(0)
{
cout<<"B ctor\n";
}
~B()
{
cout<<"B dtor\n";
}
};
int main()
{
int i = 23 ;
A* p = new B(i);
}
Run Code Online (Sandbox Code Playgroud)
可以告诉我为什么最后一行main编译?我传递一个int进入B的构造,其预期的A目的,而不是.我相信它 …
我按照三个规则实施了一个类,我遇到了崩溃.在调试时,我得出结论,复制构造函数反复调用自身而不是调用相等运算符.为什么会这样?它不应该调用相等运算符吗?
#include <iostream>
#include <deque>
#include <cstdlib>
#define LENGTH 128
typedef struct tDataStruct
{
char strA[LENGTH];
char strB[LENGTH];
int nNumberOfSignals;
double* oQueue;
tDataStruct()
{
nNumberOfSignals = 0;
//oQueue = NULL;
memset(strA, 0, LENGTH);
memset(strB, 0, LENGTH);
}
~tDataStruct()
{
if (NULL != oQueue)
{
delete[] oQueue;
oQueue = NULL;
}
}
tDataStruct(const tDataStruct& other) // copy constructor
{
if (this != &other)
{
*this = other;
}
}
tDataStruct& operator=(tDataStruct other) // copy assignment
{
if (this == &other)
{ …Run Code Online (Sandbox Code Playgroud) c++ ×11
rule-of-three ×11
c++11 ×1
constructor ×1
destructor ×1
inheritance ×1
resources ×1
visual-c++ ×1
winapi ×1
windows ×1