码迷,mamicode.com
首页 > 其他好文 > 详细

第15章 面向对象程序设计

时间:2016-01-14 23:45:45      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

面向对象的核心是:数据抽象、继承、动态绑定

数据抽象:将类的接口与实现分离

继承:对类型的相似关系进行定义建模

动态绑定:忽略相似类的区别,统一使用它们的对象

15.2基类与派生类

class Base 
{
public:
    Base() = default;
    Base(int value) :value(value){}
    virtual int get_value() { return value; };
    virtual ~Base() = default;
private:
    int value;
protected:
    void change_value() { value++; }
};

基类都应该定义一个虚函数,这样在delete一个指向派生类对象的基类指针所指向new分配的空间时,能会有理想的析构函数调用(先调用派生类的析构函数,再调用基类的。否则将会仅调用基类的析构函数)。

class Derived final:public Base
{
public:
    Derived() = default;
    Derived(int value) :Base(value) {}
    int get_value() override { return value*value; }
};

派生类覆盖基类的虚函数,可以使用(不必须,旧标准没有)override关键字,同时派生类的此函数自动成为virtual的,不管加不加virtual关键字。

final表明这个类不能被继承。

如果需要喜用被override的基类成员,需要加上基类的作用域Base::

15.2.3类型转换与继承

  1. 派生类的指针或引用可以隐式转换成基类的指针引用,反之则不行。
  2. 派生类的对象和基类的对象之间不存在期望的类型转换,因为派生类赋值给基类的时候,实际发生的是执行拷贝构造函数等过程,最终得到一个新的基类对象。

15.3虚函数/抽象基类

我们如果想调用被override的虚函数,可以使用作用域运算符进行调用。

如果虚函数=0,就是纯虚函数。有纯虚函数的类是抽象基类。我们不能创建抽象基类的对象。

15.5访问控制与继承

protect

protect成员对类的用户来讲是不可访问的

派生类protect继承基类,则基类的public成员降维成protect成员存在于派生类中

派生类的成员可以通过派生类的对象访问基类的protect成员(因为2中继承过来,相当于自己的protect成员),而不能通过基类的对象访问基类的protect成员(因为1)

private

private成员对用类的用户来讲是不可访问的。private继承过来的基类的所有成员在派生类中都将会是私有的。

派生类public继承的基类之间,才能够进行类型转换

提升基类成员的访问级别

class Base {
public:
    std::size_t size() const { return n; }
protected:
    std::size_t n;
};
class Derived : private Base {
public:
    //本来对于使用者是private的,但是提升到了public
    using Base::size;
protected:
    //本来对于使用者是private的,但是提升到了protected
    using Base::n;
};

15.6继承中类的作用域

在对象进行成员访问的时候,首先从其静态作用域中需要成员。如果找不到,去外层基类中进行查找。

如果派生类定义了和基类中名字相同的成员,则基类的成员在派生类的作用域中将会被隐藏。如果要使用,则可以通过基类的作用域进行调用。

15.7构造函数与拷贝控制

基类为虚析构函数时,使用基类的指针或引用删除(delete)派生类对象时,才能正确执行派生类的析构函数。

基类的虚析构函数(哪怕=default)还会阻止合成的移动操作。(析构函数一般和合成的移动操作有冲突)所以派生类已没有合成的移动操作,一般应该重新定义如下:

class Quote {
public:
    Quote() = default;  // memberwise default initialize
    Quote(const Quote&) = default; // memberwise copy
    Quote(Quote&&) = default;  // memberwise copy
    Quote&operator=(const Quote&) = default; // copy assign
    Quote&operator=(Quote&&) = default;  // move assign
    virtual~Quote() = default;
    // other members as before
};

15.7.4继承的构造函数

默认、拷贝、移动构造函数将不会被继承。

class Base 
{
public:
     Base(int n) { cout << "base" << endl; }
};
class Derived final:public Base
{
public:
    using Base::Base;
    //上边这个继承的基类构造函数会被编译器产生如下代码
    //但是如果用户自定义了,基类的构造函数就会被覆盖
    //Derived(int n) :Base(n) { cout << "derived" << endl; }
};

 

第15章 面向对象程序设计

标签:

原文地址:http://www.cnblogs.com/qiusuo/p/5131808.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!