使用复制构造函数C++不能正常工作

C++ with copy constructor doesn't work good

本文关键字:常工作 工作 不能 复制 构造函数 C++      更新时间:2023-10-16

我构建了一个名为 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 完整的构造函数......

Human *h = new Human("Name", *a);
                              ^----- Here it's passing in an Attribute by value

因此调用属性复制构造函数。

复制构造函数没有初始化任何东西;它只是创建和销毁一个本地临时对象。

在 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 管理类型(如智能指针和容器)而不是原始指针,以确保在完成对象后正确删除对象。处理原始指针是内存泄漏和其他灾难的秘诀。

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_pointers做到这一点要容易得多。