我构建了一个名为Attribute的对象,该对象具有完整拷贝和空构造函数。 然后我构建了另一个名为Human的对象,它包含Attribute对象。 当我尝试构建人类(使用完整的构造函数)时,它会自动调用属性复制构造函数,我不知道为什么。
这是代码:
char** d = new char*[3];
d[0] = new char[10];
d[0] = "aa";
d[1] = new char[10];
d[1] = "bb";
d[2] = new char[10];
d[2] = "cc";
Attribute *a = new Attribute(1.7, "blue", "white", "black", d, 3);
Human *h = new Human("Name", *a);
当我使用调试器并到达此行时:new Human(“Name”,* a);它会自动进入此功能:
Attribute::Attribute(Attribute& copy)
{
Attribute(copy.height, copy.eyeColor, copy.skinColor, copy.hairColor, copy.diseases, copy.numOfDiseases);
}
只有在此函数结束后,它才会启动Human完整构造函数...
答案 0 :(得分:7)
Human *h = new Human("Name", *a);
^----- Here it's passing in an Attribute by value
因此调用属性复制构造函数。
答案 1 :(得分:2)
复制构造函数没有初始化任何东西;它只是创建并销毁一个本地临时对象。
在C ++ 11中,您可以将工作委托给另一个构造函数,就像您似乎要尝试的那样:
Attribute::Attribute(Attribute const & copy) :
Attribute(copy.height, copy.eyeColor, copy.skinColor, copy.hairColor, copy.diseases, copy.numOfDiseases)
{}
从历史上看,您必须复制其他构造函数的代码,或将其移动到两个构造函数调用的函数中。
您可能还希望通过引用获取构造函数参数,以便不需要复制它们:
Human(std::string const & name, Attribute const & attribute);
除非你真的需要,否则你也应该避免使用new
。你可能想要更像
Attribute a(1.7, "blue", "white", "black", d, 3);
Human h("Name", a);
当你确实需要new
时(通常因为你希望对象比现有范围更长,或者有时候需要多态),使用RAII管理类型,如智能指针和容器,而不是原始指针,确保在完成对象后正确删除对象。杂耍原始指针是内存泄漏和其他灾难的一种方法。
答案 2 :(得分:2)
a - 是一个指针 * a - 是值
因此,如果Human的构造函数按值使用秒参数
Human::Human(char* s, Attribute a)
它将复制属性并为其使用复制构造函数。 如果您不想要此行为,可以通过指针传递参数。
Human::Human(char* s, Attribute *a)
并将其称为:
Attribute *a = new Attribute(1.7, "blue", "white", "black", d, 3);
Human *h = new Human("Name", a); // this works with pointer now. Pointer will be copied, but the class will remain in the same memory and wouldn't be copied anywhere.
如果你想到它,行为与普通值和函数类似:
void f1(int a){ a++; cout << a; }
void f2(int *a){ *a++; cout << *a; }
int b = 4;
f1(b); // It copies the value of local b to parameter a, increments local parameter a of f1 and prints it; It will print 5
cout << b; // b will remain the same. It will print 4
f2(&b); // It copies pointer, but both pointers &b and a point to the same variable b from this scope, and it's value is not copied
cout << b; // As we've worked with pointers, it was incremented in f2. It will print 5
请注意,您必须处理所有指针的责任。如果您手动创建了某些内容,请不要忘记它应该删除的位置以及在哪些情况下可能会发生泄漏。使用smart_poin来做起来要容易得多。