所读版本为《C++ Primer中文版》 第4版
第15章 面向对象编程
1.保留字virtual只在类内部的成员函数生命中出现,不能用在类定义体外部出现的函数定义上。
2.派生类只能通过派生类对象访问基类的protected成员,派生类对其基类对象的protected成员没有特殊访问权限。
例如 假设Bulk_item为Item_base的派生类,Bulk_item定义一个成员函数,接受一个Bulk_item对象的引用和一个Item_base对象的引用。price为Item_base类的protected成员
void Bulk_item::memfcn(const Bulk_item &d,const Item_base &b) { double ret = price; //ok ret = d.price;// ok ret = b.price;// error }
该函数可以访问自己对象的protected成员,Bulk_base对象的protected成员,但是,它不能访问Item_base形参的protected成员。
3.派生类中的虚函数可以访问基类函数所返回类型的派生类的引用(或指针)。
4.如果要声明(但不实现)一个派生类,则声明包含类名但是不包含派生列表。
5.将基类类型的引用或指针绑定到派生类对象对基对象没有影响,对象本身不会改变,仍为派生类对象。
6.覆盖虚函数机制
在某些情况下,希望覆盖虚函数机制并强制函数调用使用虚函数的特定版本,这时可以使用作用域操作符。
Item_base *baseP = &derived; double d = baseP->Item_base::net_price(42);这段代码强制将net_price调用确定为Item_base中定义的版本。
class base { public: std::size_t size() const{return n;} protected: std::size_t n; }; class Derived :private Base{...};
为了让size在Derived中成为public,可以在Derived的public部分增加一个using声明。
class Derived:private Base { public: using Base::size; protected: using Base::n; };
一个using声明只能指定一个名字,不能指定形参表。因此为基类成员函数名称而作的using声明将该函数的所有重载实例加到派生类的作用域。
10 如果累是使用private或Private继承派生的,则用户代码不能将派生类型对象转换为基类对象。
11.基类到派生类的自动转换时不存在的。存在派生类引用到基类引用的转换。
Bulk_item = bulk; Item_base *bulkP= &bulk;//ok Bulk_item * temP = bulkP;//ERROR12如果派生类定义了自己的复制构造函数,该复制构造函数一般应该显式使用基类复制构造函数初始化对象的基类部分。
class Derived : public Base { public : Derived(const Derived & d) { Base(d); } };初始化函数Base(d)将派生类对象d转换为它的基类部分的引用,并调用基类复制构造函数。
13.如果派生类定义自己的赋值操作符,则该操作符必须对基类部分进行显式赋值。
Derived & Derived::operator=(const Derived &rhs) { if(this!=&rhs) { Base::operator=(rhs) } return *this; }赋值操作符必须防止自身赋值。
14要保证适当的析构函数,基类中的析构函数必须是虚函数。
15.给Bulk_item类添加一个成员函数discount_policy(),返回一个保存最大数量和折扣价格的pair对象。
Bulk_item = bulk; Bulk_item *bulkP = &bulk; Item_base*baseP = &bulk; bulkP->discount_policy();//ok baseP->discount_policy();//error通过基类类型的指针或引用只能访问对象的基类部分。
16在基类和派生类中使用同一名字的成员函数,其行为与数据成员一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽。
struct Base { int memfcn(); }; struct Derived:Base { int memfcn(int); }; Derived d; Base b; b.memfcn();//ok d.memfcn(10);//ok d.memfcn();//error d.Base::memfcn();//ok通过派生类对象调用函数时,实参必须与派生类中定义的版本相匹配,只有在派生类重根本没有定义该函数时,才考虑基类函数。
17.含有(或继承)一个或多个纯虚函数的类是抽象积累。不能创建抽象类型的对象。
在函数形参表后面加上=0以指定纯虚函数。