C++默认拷贝构造函数是浅拷贝

2018-11-19  本文已影响15人  dnsir

1 引言

在C++中,会默认生成一个复制(拷贝)构造函数, 当类中出现指针时, 复制会执行浅拷贝, 即只复制指针的地址, 不会复制数据,所以在类中, 使用指针时需要注意; 如果想使用深拷贝, 可以添加复制构造函数。
提醒:**特别需要注意的是指针二字,因此在C++中要尽量避免使用指针,以前引入由于默认拷贝构造函数是浅拷贝导致的内存管理问题。

2 验证默认复制构造函数是浅拷贝

测试程序

#include <iostream>
using namespace std;

class Foo {
public:
    Foo():_data(nullptr),_len(0){}
    Foo(unsigned int len):_data(new unsigned char (len)), _len(len) {
        // std::copy()
    }
    // 默认是浅拷贝
    unsigned char* get_data() const { return _data;}
    unsigned int get_len() const {return _len;}
private:
    unsigned char* _data;
    unsigned int _len;
};
int main()
{
    Foo a(10);
    std::cout << static_cast<const void*>(a.get_data()) << std::endl;
    std::cout << a.get_len() << std::endl;
    Foo b = a;
    std::cout << static_cast<const void*>(b.get_data()) << std::endl;
    std::cout << b.get_len() << std::endl;
    return 0;
}

程序的输出结果:

0x21c7c20
10
0x21c7c20
1

也就是说a和b的_data指针值是一样,指向的是同一块内存地址,即是浅拷贝。

3 添加深拷贝拷贝构造函数

增加函数:

    Foo(const Foo& f)
    {
        _data = new unsigned char(f.get_len());
        _len = f.get_len();
    }

再次运行结果:

0x130bc20
10
0x130c050
10

发现两次_data的值是不一样,所以这次是深拷贝,C++中定义一段buffer可以使用std::vector<char>数据结构,为了避免std::vector内存频繁变动,可以提前reserve一块内存,提升性能。

上一篇下一篇

猜你喜欢

热点阅读