一、具体注意事项
(1)如果在构造函数中使用new来初始化指针成员,则应在析构函数中使用delete。
(2)new和delete必须相互兼容。new对应于delete,new[]对应于delete[]。
(3)如果有多个构造函数,则必须以相同的方式使用new,要么都带中括号,要么都不带。因为只有一个析构函数,所有的构造函数都必须与它兼容。然而,可以在一个析构函数中使用new初始化指针,而在另一个构造函数中将指针初始化为空(0或C++11中的nullptr),这是因为delete可以用于空指针(无论是带中括号还是不带中括号的new)。
注: NULL、0、nullptr,原先,空指针可以使用0或NULL来表示(在很多头文件中,NULL是一个被定义为0的符号常量)。C程序员通常使用NULL而不是0,以指出这是个指针,就像使用’\0’而不是0来表示空字符,以指出这是一个字符一样。然而C++传统上更喜欢使用0,而不是等价的NULL。但C++11提供了关键字nullptr,这是个更好的选择。
(4)应定义一个复制构造函数,通过深度复制将一个对象初始化为另一个对象。
(5)应当定义一个赋值运算符,通过深度复制将一个对象复制给另一个对象。
二、应该如何做与不应该如何做
2.1 定义的析构函数
// 析构函数释放char* str
String::~String()
{
delete[] str;
}
2.2 定义如下几种构造函数
// 第一种
String::String()
{
str = "default string";
len = std::strlen(str);
}
// 第二种
String::String(const char* s)
{
len = std::strlrn(s);
str = new char;
std::strcpy(str, s);
}
// 第三种
String::String(const std::string& st)
{
len = st.length();
str = new char[len + 1];
std::strcpy(str, s.c_str());
}
2.3 该做与不该做
第一种构造函数: 没有使用new来初始化str。对默认对象调用析构函数时,析构函数使用delete来释放str。对不使用new初始化的指针使用delete时,结果将是不确定的,并可能是有害的。
第二种构造函数: 使用了new来初始化str,但分配的内存量不正确。因此,new返回的内存块只能保存一个字符。试图将过长的字符串复制到该内存单元中,将导致内存问题。另外使用的的new不带中括号,这与析构函数delete[]不匹配。
第三种构造函数: 是正确的,可采用此种方式定义构造函数。
三、静态成员函数说明
此处额外说明下静态函数的注意事项及使用情况。
3.1 静态函数的声明与实现
声明:将成员函数声明为静态的,函数声明必须包含static关键字。如果函数定义是独立的,则其中不能包含关键字static(全局函数)。
定义:实现静态成员函数时,不需要包含static关键字。
3.2 注意事项
(1)不能通过对象调用静态成员函数,实际上,静态成员函数甚至不能使用this指针。如果静态成员函数是在公有部分声明的,则可以通过使用类名和作用域解析运算符的方式来调用它。举例如下:
// 声明与定义结合在一起
static int HowMany() { return num_strings; }
// 调用方式
int count = String::HowMany();
(2)由于静态成员函数不与特定的对象相关联,因此只能使用静态数据成员。
210

被折叠的 条评论
为什么被折叠?



