【C++学习笔记】:在构造函数中使用new时的注意事项

378 阅读2分钟

1️⃣前言

这篇笔记的内容是:在构造函数中使用new时的注意事项


2️⃣回顾

我们知道,如果在类的构造函数里使用new来初始化指针成员,则需要在析构函数里使用delete来销毁掉。并且newdelete必须相互对于与兼容,也就是说new对应于deletenew[]delete[].

需要注意的是,如果有多个构造函数,则必须用相同的方法来使用new语句。这是因为析构函数只有一个,构造函数里的new语句必须和析构里的delete语句相对应起来。

另外的,我们也可以在一个构造函数中使用new初始化指针成员,然后在另一个构造函数中将指针成员初始化为空。这是由于析构函数中的delete语句(无论带不带中括号[])都可以用于空指针。


3️⃣错误示例

比如说现在有一个简单String类,如下所示:

class String {
public:
	String();
private:
	int len;
	string str; 
};

下面举两个错误构造函数的例子。


错误的例1

代码如下:

String::String() {
	str = "initialization";
	len = std::strlen(str);
}

上面这个例子中并没有使用new来初始化str,而在析构函数里,对于不是new初始化的指针使用delete时,结果将是不确定,而且可能是有害的。


错误的例2

代码如下:

String::String(const char * ch) {
	len = std::strlen(ch);
	str = new char;
	std::strcpy(str, ch);
}

例2的代码中确实用到了new关键字,但是问题出在内存量的分配。即new返回的内存块只能保存一个字符,其无法将过长的字符串复制到new出来的内存单元中,所以导致了内存问题。


修改后的构造函数

以下三个代码块都是正确的构造函数示例:

String::String() {
	str = 0;
	len = 0;
}

或者是:

String::String() {
	len = 0;
	str = new char[1];
	str[0] = '\0';
}

或者是:

String::String(const String & s) {
	len = s.len;
	str = new char[len+1];
	std::strcpy(str, s.str);
}

4️⃣写在最后

好了,本篇笔记就到写这,欢迎大家到评论区一起讨论!