C专家编程(学习笔记)_第11章 你懂得C,所以C++不在话下

1.初识OOP

        面向对象编程很自然地把使用对象作为程序设计的中心主题。面向对象编程的特点是继承和动态绑定,C++通过类的派生支持继承,通过虚拟函数支持动态绑定,虚拟函数提供了一种封装类体系实现细节的方法。

术语             定义
抽象  它是一个去除对象中不重要的细节的过程,只有那些描述对象的本质特征的关键点才被保留。抽象是一种
      设计活动,其它的概念都是提供抽象的OOP特性;
类    类是一种用户定义类型,就好像是int这样的内置类型一样。内置类型已经有了一套完善的针对它的操作,
      类机制也必须允许程序员规定它所定义的类能够进行的操作,类里面的任何东西被称为类的成员;
对象  某个类的一个特定变量,就像j可能是int类型的一个变量一样.对象也可以被称作类的实例;
封装  把类型、数据和函数组合在一起,组成一个类.在C语言中,头文件就是一个非常脆弱的封装实例.它之所以是
      一个微不足道的封装例子,是因为它的组合形式是纯词法意义上的,编译器并不知道头文件是一个语义单位;
继承  这是一个很大的概念__允许类从一个更简单的基类中接收数据结构和函数.派生类获得基类的数据和操作,
      并可以根据需要对它们进行改写,也可以在派生类中增加新的数据和函数成员.在C语言里不存在继承的概念
     没有任何东西可以模拟这个特性;

 2.抽象——取事物的本质特性

       在软件中,抽象是非常有用的,因为它允许程序员实现下列目标:

  • 隐藏不相关的细节,把注意力集中在本质特征上;
  • 向外部世界提供一个“黑盒子”接口,接口确定了施加在对象之上的有效操作的集合,但它并不提示对象在内部是怎样实现他们的;
  • 把一个复杂的系统分解成几个相互独立的组成部分,这可以做到分工明确,避免组件之间不符合规则的相互作用;
  • 重用和共享代码;

   抽象建立了一种抽象数据类型,C++使用类这个特性来实现它。它提供了一种自上而下的、观察数据类型属性的方法来看待封装:把用户定义类型中的各种数据和方法组合在一起。它同时也提供了一种自底向上的观点来看待封装:把各种数据和方法组合在一起实现一种用户定义类型。

3.封装——把相关的类型、数据和函数组合在一起

      把抽象数据类型进而它们的操作捆绑在一起的时候,就是在进行“封装”。程序艺术的当前状态是面向对象语言,它们通过把用户定义的数据结构和用户定义的能够在这些数据结构上进程操作的函数捆绑在一起实现了数据的完整性。别的函数无法访问用户定义类型的内部数据。这样,强类型就从预定义类型扩展到用户定义类型。

4.展示一些类——用户定义类型享有和预定义类型一样的权限

       C++的类机制实现了OOP的封装要求,类就是封装的软件实现。类也是一种类型,可以对它进行很多操作。类就是用户定义类型加上所有对该类型进行的操作,类经常被实现的形式是:一个包含多个数据的结构,加上对这些数据进行操作的函数的指针。C++类允许用户定义类型:

  • 把用户定义类型和施加在它们上面的操作组合在一起;
  • 具有和内置类型一样的特权和外观;
  • 可以用更基本的类型创建更复杂的类型;

5.访问控制

public     属于public的声明在类的外部可见,并可按需要进行设置、调用和操作。一般的原则是不要把类的 
           数据做成public,因为让数据保持私有才符合面向对象编程的理论之一:只有类本身才能改变自己 
           的数据,外部函数只能调用类的成员函数,这就保证了数据只会以合乎规则的方式被更新;
protected  属protected的声明的内容只能由该类本身的函数以及该类所派生的类函数使用;
private    属private的声明只能被该类成员函数使用,在类外部是可见的(名字是已知的),但却是不能访问;

另外还有两个关键字也会影响访问控制,它们是friend和virtual;

6.声明

       C++类的声明就是正常的C声明,内容包括函数、类型(包括其他类)或数据,类把它们实现捆在一起。

类的大致实现如下:
class Fruit{ public: peel(); slice(); juice();
             private: int weight,calories_per_oz;
           };

7.如何调用成员函数

      每个成员函数都有一个this指针参数,它是隐式赋给该函数的,它允许对象在成员函数内部引用对象本身。

class Fruit { public: void peel();
              private: int weight,calories_per_oz;
            };

void Fruit::peel(){ printf("this ptr=%p",this);
                    this->weight--;
                    weight--;}

Fruit apple;
printf("address of apple=%x",&apple);
apple.peel();

构造函数和析构函数

       绝大多数类至少具有一个构造函数。当类的一个对象被创建时,构造函数被隐式地调用,它负责对象的初始化。与之相对应,类也存在一个清理函数,称为析构函数,当对象被销毁时,析构函数被自动调用。构造函数和析构函数是非常有用的,因为类外部的任何函数都不能访问类的private数据成员。因此,需要类内部有一个特权函数来创建一个对象并对其进行初始化。相对于C语言,这样一个小小的飞跃,在C语言中,只能使用赋值符号在变量定义时对它进行初始化,或干脆使它保持未初始化状态。

class Fruit { public: void peel();
              Fruit(int i,int j);//构造函数
              ~Fruit();  //析构函数
              private: int weight,calories_per_oz;
            };
//构造函数
Fruit::Fruit(int i,int j){weight=i;calories_per_oz=j;}

//对象声明时由构造函数进行初始化
Fruit melon(4,5),banana(12,8);

8.继承——复用已经定义的操作

       当一个类沿用或定制它的唯一基类的数据 结构和成员函数时,它就使用了单继承。从一个类派生另外一个类,使前前者所有的特征在后者中自动可用。它可以声明一些类型,这些类型可以共享部分或全部以前所声明的类型,它也可以从超过一个的基类型共享一些特征。

C++如何进行继承 
继承在两个类之间(而不是两个函数之间)进行。
基类的例子如下:
class Fruit{
    pubilc:
        peel();
        slice();
        juice();
    private:
        int weight,calories_per_oz;
    };
派生类的例子如下:
class Apple:public Fruit{
    public:
        void make_candy_apple(float weight);
        void bob_for(int tub_id,int number_of_attempts);
    };
对象声明的例子如下:
Apple teachers;

9.多重继承——从两个或更多的基类派生

       多重继承允许把两个类组合成一个,这样结果类对象的行为类似于这两个类的对象中的任何一个。

10.重载——作用于不同类型的同一操作具有相同的名字

       重载就是简单地复用一个现存的名字,但使它操作一个不同的类型。重载运行程序员复用函数名和绝大多数的操作符如+、=、*、-、[]和()等,赋予它们新的含义,以便用于用户定义类型。

11.C++如何进行操作符重载

以重载“+”操作符为例:
class Fruit { public: void peel();slice();juice();
                    int operator+(Fruit &f); //重载“+”操作符
              private: int weight,calories_per_oz;
            };
然后为重载后的操作符提高一个函数体:
int Fruit::operator+(Fruit &f){
    printf("calling fruit addition\n"); //这样就可以看到它被调用
    return weight+f.weight;
}

重载后的加法操作符函数可以像下面这样调用:
Apple apple;
Fruit orange;
int ounces=apple+orange;
重载后的操作符优先级和操作数与原先的操作符相同.

12.C++的输入/输出(I/O)

        C++有一个iostream.h头文件提供I/O接口,使I/O操作更为方便。C++使用<<操作符(输出)和>>操作符(输出)来代替C语言中的putchar()和getchar()等函数.。

13.多态——运行时绑定

        在C++中,它的意思是支持相关的对象具有不同的成员函数(但原型相同),并允许对象与适当的成员函数进行运行时绑定。C++通过覆盖支持这种机制——所有的多态成员函数具有相同的名字,由运行时系统判断哪一个最为合适。在成员函数前面加上virtual关键字告诉编译器该成员函数是多态的(也就是虚函数)。

      多态是指一个函数或操作符只有一个名字,但它可以用于几个不同的派生类型的能力。每个对象都实现该操作的一种类型,表现一种最合适自身的行为。它始于覆盖一个名字——对同一个名字进行复用,代表不同对象中的相同概念。多态非常有用,因为它意味着可以给类似的东西取相同的名字。运行时系统在几个名字相同的函数中选择正确的一个进行调用,这就是多态。

14.解释

       当想用派生类的成员函数取得基类的同名函数时,C++要求你必须预先通知编译器,通知的方法就是在可能被取代的基类成员函数前面加上virtual关键字。

15.C++如何表现多态

        单继承通常通过在每个对象内包含一个vptr指针来实现虚拟函数。vptr指针指向一个叫做vtbl的函数指针向量。每个类都有这样一个向量,类中每个虚拟函数在该向量都有一条记录。

16.C++的其它要点

        异常,模板,内联函数,new和delete操作符,传引用调用。

C++的一个简单子集
尽量使用的C++特性:
类;构造函数和析构函数,但只限于函数体非常简单的例子;重载,包括操作符重载和I/O;单重继承和多态;
避免使用的C++特性:
模板;异常;虚基类;多重继承;

C++语言的复用性帮助其获得更大的成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值