习题选自:C Primer Plus(第六版) 内容仅供参考,如有错误,欢迎指正 !
- c 使用new和delete运算符来动态控制内存。
- 对于静态成员,要在类声明之外使用单独语句进行初始化,因为静态类成员函数是单独存储的,而不是对象的组成部分,而且初始化是在方法文件中,而不是在头文件中,这是因为类声明位于头文件中,程序可能将头文件包括在其他几个文件中,如果在头文件中初始化,将出现多个初始化语句副本,从而引发错误。但如果静态成员是整形或枚举型const,则可以在类声明中初始化。
- 私有静态变量有且仅在初始化时,才可以在外部访问。
- 复制构造函数用于将一个对象复制到新创建的对象中,它用于初始化过程中(包括按值传递参数)。
复习题
1. 假设String 类有如下私有成员:
代码语言:javascript复制
class String
{
private:
char * str; //points to string allocated by new
int len; //holds length of string
//...
};
a. 下述默认构造函数有什么问题?
代码语言:javascript复制
String ::String() {}
b. 下述构造函数有什么问题?
代码语言:javascript复制
String:: String (const char* s)
{
str = s:
len = strlen(s);
}
c. 下述构造西数有什么问题?
代码语言:javascript复制
String: :String (const char* s)
{
strcpy(str, s);
len = strlen(s);
}
a. 语法是正确的,但该构造函数没有初始化str指针。该构造函数应该使用new[]来初始化它,或者将其设置为NULL。
b. 该构造函数没有创建新的字符串,只是复制了原有字符串的地址,它应当使用new[]和strcpy()。
c. 它虽然复制了字符串,但没有给他分配存储空间,应使用new char[len 1]
来分配适当数量的内存。
2. 如果您定义了一个类,其指针成员是使用 new 初始化的,请指出可能出现的3个问题以及如何纠正这些问题。
可能出现的:
- 问题一:当对象过期的时候,对象的成员指针指向的数据仍保留在内存中,造成内存泄漏。 在析构函数中删除构造函数中new分配的内存,来解决该问题。
- 问题二:如果使用对象初1始化为另一个对象2时,采用默认初始化的方式,则在对象1过期后,在对象2过期过程中,其析构函数会对同一块内存释放两次,造成错误。 定义一个复制构造函数,使初始化复制指针指向的数据,而不是复制指针指向的地址。
- 问题三:将一个对象赋给另一个对象也将导致两个指针指向同一个数据。 重载赋值运算符,使之复制数据,而不是指针。
3. 如果没有显式提供类方法,编译器将自动生成哪些类方法?请描述这些隐式生成的函数的行为。
如果没有显示提供方法,c 将自动生成以下成员函数:
- 构造函数:默认构造函数不完成任何工作,但使得能够声明数组和未初始化对象。
- 复制构造函数:默认赋值构造函数使用成员赋值。
- 赋值运算符:默认赋值运算法使用成员赋值。
- 析构函数:默认析构函数不完成任何工作。
- 地址运算符:隐式地址运算符返回调用对象的地址(即this指针的值)。
4. 找出并改正下述类声明中的错误:
代码语言:javascript复制
class nifty
{
// data
char personality[];
int talents;
// methods
nifty();
nifty(char * s);
ostream & operator<<(ostream & os, nifty & n);
}
nifty:nifty()
{
personality = NULL;
talents = 0;
}
nifty:nifty(char * s)
{
personality = new char [strlen(s)];
personality = s;
talents = 0;
}
ostream & nifty:operator<<(ostream & os, nifty & n)
{
os << n;
}
应将personality成员声明为字符数组或car指针,或者将其声明为String对象。该声明没有将方法设置为公有的。修改后:
代码语言:javascript复制#include <iostream>
#include <cstring>
using namespace std;
class nifty
{
private: // optional
char personality[40]; // provide array size
int talents;
public: // needed
// methods
nifty();
nifty(const char * s);
friend ostream & operator<<(ostream & os, const nifty & n);
}; // note closing semicolon
nifty::nifty()
{
personality[0] = '