1.派生类从基类那里继承了什么?
答:数据成员、非构造函数和析构函数、默认赋值运算符的方法。
基类的私有、保护、公有成员和方法,分别成为派生类的私有、保护、公有的成员和方法,但部分例外。
2.派生类不能从基类那里继承什么?
答:①构造函数(包括默认和复制);②析构函数;③赋值运算符;④友元
3.假设baseDMA::operator=()函数的返回类型为void,而不是baseDMA&,这将有什么后果?如果返回类型为baseDMA,而不是baseDMA&,又将有什么后果?
答:
情况①不能使用连续赋值,如:某对象=baseDMA类对象=某对象;
情况②将额外创造一个临时对象,占用更多内存和计算,将调用复制构造函数,对于使用new分配内存的数据成员,可能导致出问题。
4.创建和删除派生类对象时,构造函数和析构函数调用的顺序是怎样的?
答:
①调用构造函数时,会先调用基类的构造函数,再调用派生类的构造函数;
②调用析构函数时,会先调用派生类的析构函数,再调用基类的析构函数。
③如果是连续派生,最早的构造函数会被先调用,然后依次调用;析构函数则相反
5.如果派生类没有添加任何数据成员,它是否需要构造函数?
答:
如果基类有默认构造函数,那么可以不需要;
如果基类没有默认构造函数,那么需要。
答案说需要,但我实际测试,如果基类有默认构造函数,那么派生类省略构造函数也是可以的。
6.如果基类和派生类定义了同名的方法,当派生类对象调用该方法时,调用的是哪个方法?
答:
调用的是派生类的方法。
7.在什么情况下,派生类应定义赋值运算符?
答:
在派生类新增的数据成员是指针时,需要定义赋值运算符。(默认赋值不正确则需要)
8.可以将派生类对象的地址赋给基类指针吗?可以将基类对象的地址赋给派生类指针吗?
答:
前者是可以的,相当于基类指针指向派生类对象;
后者一般不行,因为这样做的结果不确定,如果派生类指针指向基类对象,并使用了派生类的方法,就可能导致错误。
9.可以将派生类对象赋给基类对象吗?可以将基类对象赋给派生类对象吗?
答:
前者是可以的,会调用复制构造函数或者赋值运算符,然后将派生类对象强制类型转换为基类对象完成。
后者如果没有显式声明以基类对象为参数的构造函数、或赋值运算符,那么是不行的。
10.假设定义了一个函数,它将基类对象的引用作为参数。为什么该函数也可以将派生类对象作为参数?
答:
因为基类的指针、引用,可以指向派生类的对象,但它只能使用基类的方法。
11.假设定义了一个函数,它将基类对象作为参数(即函数按值传递基类对象),为什么该函数也可以将派生类对象作为参数?
答:
因为在按值传递中,派生类对象被强制类型转换为了基类对象来使用(使用基类复制构造函数创造了一个基类的对象),所以可以。
12.为什么通常按引用传递比按值传递对象的效率更高?
答:
因为按引用传递不需要创造临时对象,也不需要使用复制构造函数,节约了从实参到形参,从函数内部对象到函数返回值过程中创造临时对象函数的时间和计算,因此效率更高。按引用传递,还可以确保函数从虚函数受益
13.假设Corporation是基类,PublicCorporation是派生类,再假设这两个类都定义了head()函数,ph是指向Corporation类型的指针,且被赋给了一个PublicCorporation对象的地址。如果基类将head()定义为:
a.常规非虚方法;
b.虚方法;
则ph->head()将被如何解释:
答:
a被解释为调用基类的方法;
b被解释为调用派生类的方法。
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 al_sq_ft;
public:
House(){all_sq_ft+=kit_sq_ft;}
double area(const char* s)const {cout<<s; return all_sq_ft;}
};
答:
①House类的默认构造函数,没有初始化列表;
②House类的数据成员all_sq_ft没有被初始化(无赋值);
③House类的方法House(),是不能访问基类Kitchen的私有成员的;
④违反了is-a模型,不适合用公有继承。
⑤书上说:House的area()隐藏了Kitchen的area()版本。——但我觉得没问题啊。