C++ 拷贝构造

class MyString {
private:
	char* _data;
	size_t   _len;
	void _init_data(const char *s) {
		_data = new char[_len + 1];
		memcpy(_data, s, _len);
		_data[_len] = '\0';
	}
public:
	MyString() {
		_data = NULL;
		_len = 0;
		cout << "构造" << endl;
	}

	MyString(const char* p) {
		_len = strlen(p);
		_init_data(p);
		cout << "构造:" << _data << endl;
	}

	MyString(const MyString& str) {
		_len = str._len;
		_init_data(str._data);
		cout << "拷贝构造: " << str._data << endl;
	}

	MyString& operator=(const MyString& str) {
		if (this != &str) {
			_len = str._len;
			_init_data(str._data);
		}
		cout << "等号:" << str._data << endl;
		return *this;
	}

	virtual ~MyString() {
		if (_data != NULL) {
			cout << "析构:"<< _data << endl; 
			free(_data);
		}
	}
};

void Test()
{
	MyString a;// 构造
	a = MyString("Hello");// 构造:Hello 等号:Hello 析构:Hello
        MyString b = MyString("Hi");//构造:Hi(没有其他的了)
        MyString c = b;//拷贝构造:Hi
	std::vector<MyString> vec; 
	vec.push_back(MyString("World"));// 构造:World 拷贝构造:World 析构World
        //返回前:析构:World 析构:Hi 析构:Hi 析构:Hello
}

 

### C++ 拷贝构造函数的概念 拷贝构造函数是一种特殊的构造函数,它用于通过已有的对象初始化新对象。当一个对象被用来初始化另一个同类型的对象时,将会调用该类的拷贝构造函数[^1]。 #### 调用时机 拷贝构造函数会在以下几种情况自动调用: - 当用一个对象去初始化同一类型的新对象时; - 函数返回一个局部对象作为其返回值时(如果未优化); - 将对象当作实参传递给形参时(按值传递的情况)[^4]。 ### 实现与注意事项 为了确保资源管理得当并避免潜在错误,在实现拷贝构造函数时需要注意几个方面: - **深浅复制的选择**:对于指针成员变量或其他动态分配的数据结构,应决定采用深复制还是浅复制策略。通常情况下推荐使用深复制来防止多个对象共享相同数据而导致意外修改或悬空指针等问题[^3]。 - **异常安全**:在执行复杂的拷贝操作期间可能会抛出异常。因此建议遵循RAII原则,并尽可能利用智能指针等现代C++特性简化内存管理和提高程序健壮性[^2]. - **编译器生成版本的存在与否**:如果没有显式声明任何自定义形式,则编译器会提供默认版——这可能并不总是满足需求特别是涉及到复杂状态维护或是拥有非公有基类的情形下[^5]。 ### 示例代码展示 下面给出一段简单示例说明如何正确编写拷贝构造函数: ```cpp class Date { private: int* _data; public: // 构造函数 explicit Date(int day, int month, int year):_data(new int[3]{day, month, year}){} // 拷贝构造函数 Date(const Date& other){ std::cout << "Copy constructor called." << std::endl; _data = new int[3]; for (int i = 0; i < 3; ++i) { _data[i] = other._data[i]; } } ~Date(){ delete[] _data; } void Print() const{ printf("%d-%d-%d\n", (*this)[0],(*this)[1],(*this)[2]); } int operator[](size_t index)const{return _data[index];} }; // 测试部分 void test(Date d){} int main(){ Date today(7,8,2023); Date tomorrow(today); // 明确触发拷贝构造 test(tomorrow); // 隐含触发拷贝构造 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值