默认复制构造函数

Default copy constructor

提问人:JPPPPP 提问时间:10/1/2021 最后编辑:user438383JPPPPP 更新时间:10/2/2021 访问量:366

问:

我遇到了复制构造函数的想法,并使用指针作为类的成员变量。讲师告诉我,如果我们使用默认的复制构造函数为一个具有指针类型的成员变量的类创建一个实例,则默认的复制构造函数将使用浅拷贝,并导致编译器两次删除相同的内存空间。但是当我尝试使用相同的代码时,我没有发现相同的问题,并且当我从不同实例输出两个指针的地址时,输出是不同的。我想知道编译器本身是否已将其调整为默认复制构造函数的深度复制,或者代码有问题。谢谢!

#include <iostream>
 
using namespace std;
    
class Person
{
    public:
    Person(int age,int height)
    {
        m_age = age;
        m_height = new int(height);
        cout << "Person constructed function with param" << endl;
    }

    Person(const Person &p)
    {
        cout << "Person 拷贝构造函数调用" << endl;
        m_age = p.m_age;
        cout << "here" << endl;
        m_height = new int(*p.m_height);
        cout << "地址:" << &m_height << endl;
    }
        
    Person()
    {
        cout << "Person constructer function without param" << endl;
    }
    
    ~Person()
    {
        if (m_height != NULL)
        {
            delete m_height;
            m_height = NULL;
        }
            
        cout << "Person destructer" << endl;
    }
        
    int m_age = 0;
    int* m_height = NULL;
};
    
void test01()
{
    Person p1(18, 160);
        
    cout << "age of p1: " << p1.m_age <<", height:" << &p1.m_height << endl;
        
    Person p2(p1);
        
    cout << "age of p2: " << p2.m_age << ", height:" << &p2.m_height << endl;
} 
    
int main()
{
    test01();

    return 0;
}
C++ 析构函数 复制构造函数 删除运算符 default-copy-constructor

评论

4赞 Richard Critten 10/1/2021
“......默认复制构造函数将使用浅层复制...“,但是您没有使用默认复制构造函数,而是提供了自己的构造函数,它几乎可以完成所需的所有事情 - 它可能应该将 的值(而不是指针)复制到新类中。Person::Person(const Person &p)m_height
0赞 JPPPPP 10/2/2021
我现在知道我的代码哪里出了问题,我认为他们使用不同地址的原因是,在代码中,我没有输出m_height的地址,而是输出指向数据的指针的地址,这当然是两个不同的地址。

答:

2赞 Vlad from Moscow 10/1/2021 #1

在 copy 构造函数中,在此语句中:

m_age = p.m_age;

您将一个数据成员的值分配给另一个数据成员。

但在这份声明中:

m_height = new int(*p.m_height);

您没有将一个数据成员的值分配给另一个数据成员。

相反,如果你写了:

m_height = p.m_height;

然后,不同对象的两个数据成员将指向析构函数中释放的同一动态分配内存。因此,两个对象将尝试释放同一内存两次。

这就是讲师警告你的。如果不编写自己的复制构造函数来深度复制所指向的动态对象,则指针的此浅拷贝是默认编译器生成的构造函数将使用的代码类型。