C++11新特性:拷贝构造函数

C++拷贝构造函数

C++中的拷贝构造函数是一种特殊的构造函数,它用于创建一个新的对象,该对象是通过复制另一个对象的值而创建的。拷贝构造函数通常被用于参数传递和返回值传递中,以及通过值传递或者显式调用来创建副本。

拷贝构造函数的语法形式如下:

class MyClass {
public:
    MyClass(const MyClass& other) { // 拷贝构造函数
        // 执行拷贝操作
    }
};

拷贝构造函数的参数是一个常量引用,它表示要被复制的对象。在拷贝构造函数的执行过程中,我们需要创建一个新的对象,并把所有数据成员的值复制到新的对象中。

通常情况下,拷贝构造函数的实现方式如下所示:

class MyClass {
public:
    MyClass(const MyClass& other) { // 拷贝构造函数
        mData = other.mData; // 复制数据成员的值
    }
private:
    int mData;
};

但是,如果对象含有动态分配的内存,我们通常需要在拷贝构造函数中进行深拷贝,以确保新对象和原对象之间有独立的内存空间。

下面是一个示例,展示了拷贝构造函数的使用:

#include <iostream>
using namespace std;

class MyInt {
public:
    MyInt(int val) : mData(new int(val)) {}
    ~MyInt() { delete mData; }
    MyInt(const MyInt& other) : mData(new int(*other.mData)) {} // 拷贝构造函数
    int getVal() const { return *mData; }
private:
    int *mData;
};

int main() {
    MyInt a(10);
    MyInt b = a; // 调用拷贝构造函数
    cout << "a: " << a.getVal() << endl;
    cout << "b: " << b.getVal() << endl;
    return 0;
}

在这个例子中,我们定义了一个简单的类MyInt,该类包含一个指向int型数据的指针。在构造函数中,我们使用new创建了一个动态分配的内存空间。在拷贝构造函数中,我们需要使用另一个对象的值创建一个新的对象,这里使用了深拷贝的方式。

然后,我们创建了一个类MyInt的对象a,并将它的值设置为10。接着,我们将对象a的值复制给了对象b,这里会调用拷贝构造函数。最后,我们打印了对象a和对象b的值,可以看到它们的值是相同的。

C++拷贝构造函数会被隐式创建吗

如果你没有显式地定义拷贝构造函数,在需要使用拷贝构造函数的情况下,编译器会自动隐式地创建拷贝构造函数。隐式定义的拷贝构造函数将会使用其它已存在的构造函数,以深复制的方式来创建新的对象。它的语法如下:

class MyClass {
public:
    MyClass(const MyClass& other) { // 隐式拷贝构造函数
        // 执行深拷贝操作
    }
};

需要注意的是,如果你已经显式定义了拷贝构造函数,那么编译器就不会再隐式定义一个拷贝构造函数了。

下面是一个例子,展示了当你没有显式定义拷贝构造函数时,编译器会自动隐式创建拷贝构造函数:

#include <iostream>
#include <string>
using namespace std;

class MyClass {
public:
    MyClass(string name) : mName(name) {}
    string getName() const { return mName; }
private:
    string mName;
};

int main() {
    MyClass obj1("Alice");
    MyClass obj2 = obj1; // 调用隐式拷贝构造函数
    cout << "obj1: " << obj1.getName() << endl;
    cout << "obj2: " << obj2.getName() << endl;
    return 0;
}

在这个例子中,我们定义了一个简单的类MyClass,该类包含一个名字成员变量mName。在构造函数中,我们使用给定的名字初始化mName。在main()函数中,我们创建了一个类MyClass的对象obj1,并将其名字设置为"Alice"。接着,我们将对象obj1的值复制给了对象obj2。由于我们没有显式定义拷贝构造函数,因此编译器将自动隐式地创建一个拷贝构造函数。最后,我们打印了对象obj1和对象obj2的名字,可以看到它们的名字是相同的。

有默认拷贝构造函数为什么还要显示创建拷贝构造函数

即便C++提供默认的拷贝构造函数,但是在一些情况下,我们需要自己显示地定义拷贝构造函数。以下是一些需要显示定义拷贝构造函数的情况:

  1. 类中包含指针成员时,需要进行深拷贝,否则会出现浅拷贝的问题。例如:
class Person {
public:
    char* name;
    int age;
    Person(const char* n, int a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
        age = a;
    }
    // 拷贝构造函数
    Person(const Person& p) {
        name = new char[strlen(p.name) + 1];
        strcpy(name, p.name);
        age = p.age;
    }
    // 析构函数
    ~Person() {
        delete[] name;
    }
};
  1. 类中包含文件指针时,需要在拷贝构造函数中打开一个新的文件指针,并复制原来指向的文件内容。

  2. 禁止浅拷贝。

  3. 调用基类的拷贝构造函数。我们可以在派生类的拷贝构造函数中调用基类的拷贝构造函数。

总之,需要显示定义拷贝构造函数的情况多种多样,需要根据具体情况来决定是否需要定义。

C++深浅拷贝区别

在C++中,拷贝是一个经常遇到的操作。有时候我们需要创建一个与原始对象一模一样的新对象,这个过程有两种方式,即浅拷贝和深拷贝。

浅拷贝(Shallow Copy)只复制指针或引用,而不复制堆上的实际数据。它只是增加一个指向相同数据的指针或引用,也就是说,浅拷贝操作并不分配新内存给新对象。因此,原始对象和拷贝对象共享同一块内存,对一个对象的修改会影响另一个对象。当我们删除原始对象时,同时也会删除被拷贝对象的指针或引用,这可能会引起程序错误。

深拷贝(Deep Copy)则完全复制整个对象,包括堆上的实际数据。深拷贝会为新对象分配新的内存空间,并将原始对象的所有内容复制到新的内存空间。因此,拷贝对象和原始对象是完全独立的,互相没有影响。

总之,使用浅拷贝时,需要注意它们之间的关系,避免在一个对象上进行修改时影响到另一个对象;而深拷贝将创建一个全新的对象,避免了这个问题,但也需要更多的内存空间。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值