第十三章
1.派生类从基类那里继承了什么?
基类的共有成员成为派生类的共有成员。基类的保护成员成为派生类的保护成员。基类的私有成员被继承,但不能直接访问。
2.派生类不能从基类那里继承什么?
不能继承构造函数,析构函数,赋值运算符和友元
3.假设baseDMA::operator=()函数的返回类型为void, 而不是baseDMA&,这将有什么后果?如果返回类型为baseDMA,而不是baseDMA&,这又将有什么后果?
如果返回的类型为void,仍可以使用单个赋值,但不能使用连锁赋值,即可以使用baseDMA a = b,而不使用baseDMA a = b = c
如果方法返回一个对象,而不是引用,则该方法的执行速度将有所减慢,这是因为返回语句需要复制对象
4.创建和删除派生类对象时,构造函数和析构函数调用的顺序是怎么样的?
最早的构造函数最先调用,调用析构函数的顺序恰好相反
5.如果派生类没有添加任何数据成员,它是否需要构造函数?
需要,每个类必须有自己的构造函数。如果派生类没有添加新成员,则构造函数可以为空,当必须存在
6.如果基类和派生类定义了同名的方法,当派生类对象调用该方法时,被调用的将是哪个方法?
将导致派生类的同名方法隐藏基类的方法,只有当派生类没有重新定义同名方法或使用基类的作用域运算符,派生类才会调用基类方法。
7.在什么情况下,派生类应定义赋值运算符?
如果派生类构造函数使用new或new[ ]运算符来初始化类的指针成员,则应定义一个赋值运算符。更普遍的说,如果对于派生类成员来说,默认值不正确,则应定义赋值运算符。
8.可以将派生类对象的地址赋给基类指针吗?可以将基类对象的地址赋给派生类指针吗?
当然,可以将派生类对象的地址赋给基类指针,但只有通过显示类型转换,才可以将基类对象的地址赋给派生类指针(向下转换),而使用这样的指针不一定安全。
9.可以将派生类对象赋给基类对象吗?可以将基类对象赋给派生类对象吗?
是的,可以将派生类对象赋给基类对象。对于派生类中新增的数据成员都不会传递给基类对象。然而,程序将使用基类的赋值运算符。仅当派生类定义了转换运算符(即包含将基类引用作为唯一参数的构造函数)或使用基类为参数的赋值运算符时,相反方向的赋值才是可能的。
10.假设定义了一个函数,它将基类对象的引用作为参数。为什么该函数也可以将派生类对象作为参数?
因为C++允许基类引用指向从该基类派生而来的任何类型
11.假设定义了一个函数,它将基类对象作为参数(即函数按值传递基类对象)。为什么该函数也可以将派生类对象作为参数?
按值传递对象将调用复制构造函数,由于形参是基类对象,因此将调用基类的复制构造函数。复制构造函数以基类引用为参数,该引用可以指向作为参数传递的派生对象。最终结果是,将生成一个新的基类对象,其成员对应于派生对象的基类部分。
12.为什么通常按引用传递对象比按值传递对象的效率更高?
C++按值传递对象的过程是一个对象的复制过程,其优点是保护对象的源不被修改。若按引用传递对象,则传递的对象是本身,并没有对象的复制过程。
13.假设Corporation是基类,PublicCorporation是派生类。再假设这两个类都定义了head()函数,ph是指向Corporation类型的指针,且被赋给一个PublicCorporation对象的地址。如果基类将head()定义为:
a.常规非虚方法:没有使用virtaul关键字修饰,它们在编译时被动态绑定,也称为静态绑定,意味着编译器在编译时就确定了要调用哪个函数
b.虚方法:由virtual修饰的类成员函数,在运行时根据对象的类型进行绑定。使用虚方法时,可以在基类(父类)中定义它,子类重写来实现自己的实现。虚函数的作用就是实现“动态联编”,也就是在程序的运行阶段动态地选择合适的成员函数
则ph->head()将被如何解释?
在类的继承中,如果派生类和基类有同名的函数,通常基类的同名方法会被派生类隐藏,调用基类的时候需要添加作用域。如果head()是一个常规非虚函数,则ph->head()将会根据指针的类型判断,并调用基类的方法,即Corporation::head()如果head()是一个虚方法,则ph->head()将会根据实际对象的类型调用派生类的方法,即PublicCorpation::head()
14.下述代码有什么问题?
class Kitchen
{
private:
double kit_sq_ft;
public:
Kitchen() {kit_sq_ft = 0.0;}
virtual double area() const {return kit_sq_ft * kit_sq_ft;}
};
class House :public Kitchen
{
private:
double all_sq_ft;
public:
House() {all_sq_ft += kit_sq_ft;}
double area(const char*s) const
{
std::cout << s;
return all_sq_ft;
}
};
在类的继承中,作为派生类,House是没有办法直接访问Kitchen基类的私有数据成员的的,两个函数的特征标不同,所以虚函数的功能并没有发挥,仅派生类的函数隐藏了基类的函数