使用VC6打开考生文件夹proj3下的工程proj3,其中定义了一个字符串变量类StringVar。类成员的说明在程序注释中。请在//********333******** 和 /...
Hello Kitty
此情况下程序的输出应该是:
Hello Kitty
Borg
Borg
注意:只需在//********333******** 和 //********666******** 之间填入所编写的若干语句,不要改动程序中的其他内容。
参考解析: 【参考答案】
StringVar::StringVar(int size) : max_length(size) //使用成员初始化列表初始化max_length
{
value = new char[size];
value[0] = ‘\0’;
}
StringVar::StringVar(const char a[])
{
max_length = strlen(a) + 1;
value = new char[max_length];
strcpy(value, a);
}
StringVar::StringVar(const StringVar& strobj)
{
max_length = strobj.max_length;
value = new char[strlen(strobj.value) + 1];
strcpy(value, strobj.value);
}
void StringVar::input_line(istream& ins)
{
int i = 0;
char ch;
while (i <max_length - 1 && (ch = ins.get()) != '\n')
{
value[i++] = ch;
}
value[i] = '\0';
}
ostream& operator <<(ostream& outs, const StringVar the_string)
{
outs <<the_string.getValue() < <endl;
return outs;
}
【考点分析】
本题考查构造函数和析构函数的定义、类的成员函数、 重载流运算符>>和插入运算符<<和预定义流对象。
【解题思路】
由StringVar.h这个头文件可知:头文件中定义了StringVar类,它包含的成员信息如下:
两个数据成员:char *类型的value,指向字符串的首地址;int类型的max_length,表示字符串的最大长度。两个构造函数:接收int类型的构造函数和接收const char a[]的构造函数。一个复制构造函数:用参数strobj对象的成员值给当前对象的成员赋值;析构函数:使用delete []释放value指向的地址空间;length()成员函数:返回成员value指向的字符串长度;input_line()成员函数:使用输入流参数输入一个字符串,保存到value指向的内存空间;getValue()成员函数:常成员函数,返回value的值。
另外类定义体外部还声明一个重载“ < <”运算符函数,将StringVar对象中value指向的字符串输出,并返回输出流outs的引用
头文件中,已经给出的定义有:析构函数、length()函数和getValue()函数,所以需要我们完成的函数定义有:构造函数、复制构造函数、input_line()函数和重载的“ < < < <”运算符函数
题意指出,size为字符串长度(字符个数)初始值,字符串内容初始化为空串,所以需要使用size设置成员max_length,为value申请size个字符的存储空间,并把value的第一个字符设置为’\0’表示空串,这样保证析构函数的delete []也是正确的,构造函数定义如下:
StringVar::StringVar(int size) : max_length(size) //使用成员初始化列表初始化max_length
{
value = new char[size];
value[0] = ‘\0’;
}
题意指出,使用参数数组a的内容初始化对象的成员,即将数组a中的内容,存放到value指向的内存空间,由于value是使用new分配的(保证析构函数的delete []是正确的),所以不能简单的把数组a的首地址赋给value,需要将数组a的内容复制到value指向的内存空间中,另外成员max_length,初值最小必须是value指向的内存空间长度,即value指向的字符串长度+1(题意中max_length表示字符个数的最大值,所以需要包含字符串结束符’\0’),此构造函数定义如下:(此构造函数的形参必须传入的是字符串,如果是字符数组,必须传入数组的长度,以防数组a的最后一个字符不是结束符’\0’,此时strlen()函数获取的长度,就不是字符数组a的字符个数)
StringVar::StringVar(const char a[])
{
max_length = strlen(a) + 1;
value = new char[max_length];
strcpy(value, a);
}
复制构造函数需要将形参strobj的成员赋给当前调用该复制构造函数的对象成员,在赋值value时,同样需要为value分配足够的内存空间,函数定义如下:
StringVar::StringVar(const StringVar& strobj)
{
max_length = strobj.max_length;
value = new char[strlen(strobj.value) + 1];
strcpy(value, strobj.value);
}
input_line()函数需要使用形参ins输入流,输入一个字符串存放到value中,题意要求可以输入空格,所以我们不能直接用输入流ins和输入运算符,因为输入运算符会丢弃空白符、空格符和制表符,可以使用输入流ins的成员函数:get()和while循环,逐个输入字符存放到value下标i的字符中,直到输入的字符为换行符或value存满(i=max_length)为止,当这两个条件满足其一,那么就应该停止输入,另外需要注意:value指向的字符串结尾,必须包含空字符’\0’,所以下标max_length-1必须是空字符,循环输入时,i取值最大为max_length-2,所以函数定义如下:
void StringVar::input_line(istream& ins)
{
int i = 0;
char ch;
while (i <max_length - 1 && (ch = ins.get()) != '\n')
{
value[i++] = ch;
}
value[i] = '\0';
}
输出运算符重载函数,题意要求将the_string通过输出流outs输出,由于the_string是StringVar对象,所以输出的应该是对象的成员value指向的字符串,根据返回值可知,函数必须返回输入流ostream的引用;另外由于第一形参是输入流outs,所以无法通过StringVar对象来调用,该函数不是类的成员函数,函数定义时,不能限定StringVar作用域,由于该函数不是类的成员函数,所以使用输出流outs输出value指向的字符串时,不能直接使用私有成员value,而是应该使用getValue()公有成员函数,返回value的值,再输出,所以函数定义如下:
ostream& operator <<(ostream& outs, const StringVar the_string)
{
outs < <the_string.getValue() < < endl;
return outs;
}