1.静态类成员
class StingBad
{
private:
char *str;
int len;
static int num_strings;
public:
StringBad(const char *s);
StringBad();
~StringBad();
};
(1)使用char指针而不是char数组:这样类声明中没有为字符串本身分配内存空间,而是在构造函数中使用new来为字符串分配内存空间。
(2)num_strings成员声明为静态存储类,类的所有对象共享一个静态成员。
在包含类方法的.cpp文件(非main.cpp)中将静态成员初始化,不能再类声明(.h)中初始化静态成员变量。
因为声明描述了如何分配内存,但是并不分配内存。
int StringBad::num_strings = 0; //创建对象并分配和初始化内存。
静态类成员是单独存储的,不是对象的组成部分,因此可以在类声明之外用单独的语句初始化。
但是,
如果静态成员是const整数类型,或者枚举型,则可以在声明中初始化。
2.使用new的构造函数
StringBad::StringBad(cosnt char *s)
{
len = strlen(s);
str = new char[len+1];
strcpy(str,s);
}
类成员str是一个指针,因此构造函数必须提供内存来存储字符串。
使用new分配足够的空间来保存字符串(len+1),然后将新内存的地址赋给成员str。
strcpy()将传递的字符串分配到新的内存中。
【字符串并不保存在对象中,字符串单独保存在堆内存中,对象仅保存了指出到哪里去查找字符串的信息】。所以,
str = s;//只保存了地址,没有创建字符串副本。
3.使用delete的析构函数
StringBad::StringBad()
{
delete []str;
}
str成员指向new分配的内存,当StringBad队形过期时,str指针也过期,但是str指向的内存仍被分配,除非使用delete将其释放。删除对象可以释放对象本身占用的内存,但是不能自动释放属于对象成员的指针指向的内存。
3.当使用一个对象来初始化另一个对象时,编译器将自动生成复制构造函数(因为她创建对象的另一个副本)
StringBad sailor = sports;
StringBad sailor = StringBad(sports);
二者等效。对应的构造函数原型为:
StringBad(const StringBad &);