自测练习题9.2
(虽然已给出答案,但其中有些地方自己弄的不是很清楚,
所以写一篇文章记录以下问题和解释)
目录
9.2找出下列各题中的错误,并说明如何改正
a)假设在Time类中声明了以下原型:
void ~Time(int);
错误:不允许析构函数返回值(或者指定返回类型)或者接收参数。
改正:删除声明中的返回类型void 和参数int
修改后代码:
~Time();
b)下面是Time类的部分定义:
int Employee(string,string);
错误:不能在类定义中显式的初始化;
改正:从类定义中删除显式的初始化,并在构造函数中初始化数据成员。
解释:本题的Employee成员函数,接受了两个string类型的参数,这个成员函数的实现包括了利用成员初始化器进行的显式的初始化,因此错误在于应该在构造函数Time中对类的数据成员进行显式的初始化操作。
修改后的代码:(比较完整的写法)
class Time {
public:
Time(string name, string department); // 构造函数声明(实际修改后的代码这一行即可)
private:
string name;
string department;
};
// 构造函数的定义
Time::Time(string name, string department) : name(name), department(department) {
// 在构造函数中对数据成员进行**显式**初始化
}
补充知识 (隐式和显式初始化) :
在 C++ 中,成员变量的初始化可以分为两种方式:隐式初始化和显式初始化。
-
隐式初始化:当成员变量没有在构造函数的成员初始化列表中显式初始化时,它们将被隐式初始化。隐式初始化将会使用默认的初始化方式,例如对于基本数据类型,将会被初始化为零或默认值;对于类对象,将会调用默认构造函数进行初始化。
-
显式初始化:当成员变量在构造函数的成员初始化列表中显式指定了初始值时,就称为显式初始化。通过成员初始化列表,可以在创建对象时为成员变量指定特定的初始值,而不依赖于默认构造函数的行为。
class Example {//举例子
public:
int a; // 隐式初始化,默认为未定义的值
int b = 5; // 隐式初始化为 5
int c; // 隐式初始化,默认为未定义的值
Example(int value) : c(value) {
// 成员初始化列表中显式初始化 c
// 其他成员变量 a, b 将使用隐式初始化
}
};
c)假设在Employee类中声明了以下原型:
class Example
{
public:
Example(int y=10)
:date(y)
{
//empty body
}
int getIncrementedData () const
{
return ++data;
}//end function getIncrementedData
static int getCount()
{
cout<<"Data is "<<data<<endl;
return count;
}//end function getCount
private:
int data;
static int count;
};//end class Example
错误1:不允许构造函数返回值
改正:不存在该错误!!!int指的是参数的类型,如果employee的对象,没有给参数,那么int y=10是默认对参数进行初始化
错误2:Example的类定义有两处错误。
1)在getIncrementedData()函数中,声明为const,但是修改了对象。
改正:删除const即可。
2)在getCount()函数中,其中函数声明为static,所以不允许访问该类的任何非static成员。
改正:删除输出行 cout<<"Data is "<<data<<endl; 即可
修改后代码
class Example
{
public:
Example(int y=10)
:date(y)
{
//empty body
}
int getIncrementedData () //删除const
{
return ++data;
}//end function getIncrementedData
static int getCount()
{
//cout<<"Data is "<<data<<endl;删除该行
return count;
}//end function getCount
private:
int data;
static int count;
};//end class Example