存档

文章标签 ‘继承’

【笔记迁移】C++Primer笔记 2010/9/12

2012年2月27日  1,603 views 没有评论

C++Primer笔记 2010/9/12


15章面向对象编程


继承和构造函数:在派生类的构造函数中不能通过初始化列表直接初始化继承成员的值,但是可以在初始化列表中包含基类的构造函数来初始化基类对象。派生类构造函数总是默认的先执行基类的构造函数然后再执行派生类的初始化列表,然后是派生类构造函数函数体。 在多重继承中,派生类只能初始化直接基类,因为直接基类对它的基类已经有了处理,所以派生类只需要对自己的直接基类进行初始化就可以了。
继承, 构造函数


继承和复制控制:派生类和基类的复制控制是分开的,当使用默认的复制控制函数的时候,首先调用基类的默认复制构造函数,然后调用派生类的复制构造函数。但是一旦派生类定义了自己的复制构造函数,那么该定义将完全覆盖默认定义,在此复制构造函数中必须显式调用基类的复制构造函数,否则将会调用基类的默认构造函数对基类对象进行初始化,这会出现令人难以理解的配置:它的基类部分将保存默认值,它的自有成员部分将是另一对象的副本。

示例:

class base{};
class child : public base{
    child(const child& d):base(d)/* other member initialization */{}
}

继承, 复制构制造函数


继承和赋值操作符:赋值操作符必须防止自身赋值,这是首先要注意的。如果派生类显式定义了自己的赋值操作符,那么必须显式调用基类的赋值操作符来为基类对象赋值。
继承, 赋值操作符


继承和析构函数:派生类不需要注意基类的析构函数,编译器总是显示调用派生类对象的基类部分的析构函数,调用顺序与构造顺序相反。
继承, 析构函数


虚析构函数:为了能够在删除动态绑定指针时调用正确的析构函数,可以将基类的析构函数设为虚函数,这样删除时将调用动态绑定的真实对象的析构函数。基类析构函数几乎总是需要定
义为虚析构函数。而且虚析构函数和其他析构函数一样,如果层次中根类的析构函数为虚函数那么派生类的析构函数也将是虚函数,无论是否有显式定义。

析构函数, 虚函数


局部作用域中声明的函数不会重载全局作用域中定义的函数,派生类中定义的函数也不重载基类中定义的成员。所以说重载只会发生在同级作用域中,是一种横向操作。
如果不在派生类中定义此函数,那么可以使用派生类对象调用所有基类中此函数的重载版本,但是如果在派生类中定义了此函数名的函数,不管函数原型是否相同,都无法再通过派生类对象访问这些重载版本了。如果派生类希望使用自己定义的一个版本的此函数,同时又使用基类所定义的所有重载版本(这些版本的函数,函数原型各不相同)那么要么在派生类中重新定义所有的重载版本,要么为重载成员提供using声明。一个using声明只能指定一个名字,不带形参表。例如:在派生类中添加using base::out;就可以在派生类中重载基类的out成员了。

重载, 作用域, using


【笔记迁移】C++Primer笔记 2010/9/11

2012年2月26日  1,925 views 没有评论

15章 面向对象编程


引用和指针的静态类型(在编译时可知的引用类型或指针类型)与动态类型(指针或引用所绑定的对象的类型,这是仅在运行时可知的)可以不同,这是C++用以支持多态性的基石。


使用作用域限定符可以覆盖虚函数机制并强制函数调用使用虚函数的特定版本。
示例:

Item_base *baseP = &child;
double d = baseP ->Item_base::net_price(42);

这段代码将强制调用Item_base中定义的net_price版本,不会随baseP指针实际指向的对象而变化。
派生类虚函数调用基类版本时,必须显式使用作用于限定符。如果派生类函数忽略了这样做,则函数调用会在运行时确定并且将会是一个自身调用,从而导致无穷递归。
虚函数


虚函数的默认实参的值由调用该函数的类型定义,与对象的动态类型无关。 在同一虚函数的基类版本和派生类版本中使用不同的默认实参几乎一定会引起麻烦。如果通过基类的引用或指针调用虚函数,但实际执行的是派生类中定义的版本(引用或指针所指对象实际为派生类对象),这时就可能会出现问题,此时,为虚函数的基类版本定义的默认实参将传递给派生类定义的版本,
而派生类版本是用不同的默认实参定义的。

虚函数, 默认实参


所有的基类与派生类的关系应该遵循 派生类应反映与基类的“是一种(is a)”关系。
继承


派生类可以恢复继承成员的访问级别。例如类A private实现继承类B,类B中有Public成员size,那么,在类A的public部分中增加using声明即可。
示例:

class A :private B{
public:
using B::size;
}

派生类可以恢复继承成员的访问级别,但是不能使访问级别比基类中原来指定的更严格或更宽松。
使用class保留字派生时默认具有private继承,使用struct时默认具有public继承,但是使用默认继承是非常罕见的,不论何时都应显式指明继承的派生保护级别。
继承, 访问级别


继承与静态成员:如果基类定义了static成员,则整个继承层次中只有这一个这样的成员。无论从基类派生出了多少个派生类,所有这些类在访问static成员时所访问的是同一个成员。
继承, static


基类与派生类的转换:派生类可以转换为基类但仅仅局限于引用与指针还有用派生类对象对基类对象进行初始化,初始化时派生类的自有部分被忽略。
从基类到派生类没有自动的转换,就算是基类的指针指向派生类对象,当用这个指针给派生类指针赋值时也会出现编译错误,因为编译器无法只掉动态的绑定是否安全,只能通过静态类型来盘判断操作是否安全,如果此操作真的安全,那么可以使用static_cast强制编译器进行转换,或者使用dynamic_cast申请在运行时检查。

继承, 转换


分类: 心得笔记 标签: , , ,