C++和C基本特性

c与c++

1. 初识OOP

object-oriented paradigm(面向对象编程模型)
面向对象编程的特点:继承和动态绑定,C++通过类的派生支持继承,通过虚拟函数支持动态绑定,虚拟函数提供一种封装体系 实现细节的方法。

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

2. 抽象–取事务的本质

抽象允许程序员实现下列目标

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

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

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

C++类允许用户自定义类型

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

类:用户定义类型加上所有对该类型进行的操作
实现形式:一个包含多个数据的结构,加上这些数据进行操作的函数的指针

5. 访问控制

访问控制是一个关键字,他说明谁可以访问接下来声明的数据或函数

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

6. 声明

c++类的声明就是正常的c声明,内容包括函数、类型(包括其他类)或数据,类把他们捆在一起。类中每个函数声明都需要一个实现,他可以在类里面实现,也可以在类的外面实现(通常做法)。

class Fruit{public : peel();slice();juice();
            private: int weight, calories_per_oz;};
Fruit melon; //类的一个实例
C语言申明:
返回值 函数名(参数列表){ /* 实现 */}
c++语言声明:
返回值 类名::函数名(参数列表){ /* 实现 */}

"::"被称为全局范围分解符

内部实现

class Fruit{public : peel(){printf("in peel");};
            slice();juice();
            private: int weight, calories_per_oz;};

外部实现

class Fruit{public : peel();slice();juice();
            private: int weight, calories_per_oz;};
void Fruit::peel(){printf("in peel");}

以上两种语法等价,第二种更常见,它的好处是可以通过使用头文件,使源代码组织形式更为清晰。第一种通常用于非常简短的函数,他的代码在编译时在声明处自动展开,这样在运行时就不必付出函数调用的代价。

7. 如何调用成员函数

  1. 在调用成员函数前面附上类的实例名
Fruit melon, orange, banana;

main()
{
    melon.slice();
    orange.juice();
    return 0;
}
  1. 每个成员函数都有一个this指针参数,它是隐士赋给该函数的,他允许成员函数内部引用自身。
class Fruit{public : peel();;
            private: int weight, calories_per_oz;};
void Fruit::peel(){printf("in peel");
                    this->weight--;
                    weight--;}
Fruit apple;
printf("address of apple= %x", &apple);
apple.peel();
  1. 构造函数和析构函数
    • 绝大多数类至少具有一个构造函数。当类的一个对象被创建时,构造函数隐式调用
    • 与之相对应,类存在一个清理函数,被称为析构函数,当对象被销毁时,析构函数自动调用
      C语言中,只能使用赋值符号在变量定义时对他进行初始化,或干脆保持未初始化状态

构造函数总是类的名字是一样的

class Fruit{public : peel();slice();juice();
            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), banena(12, 8)

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

从一个类派生另外一个类,使前者所有的特征在后者中自动可用,他可以声明一些类型,这些类型可以共享部分或全部以前所申明的类型。他也可以从超过一个的基类共享一些特征

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

// 派生类的例子
class Apple:public Fruit
{
    Public : 
        void make_candy_apple(float weight);
        void bob_for(int tun_id, int number_of_attempts);
};

// 对象声明的例子
apple teachers;

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

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

重载:简单的复用一个现存的名字,但使她操作一个不同类型。他可以是函数的名字,也可以是一个操作符。

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

class Fruit{public : 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++的输入输出

C++有一个iostream.h头文件,提供I/O接口,使I/O操作更为方便,符合OOP理念

c++ 使用<<操作符(输出,或称“插入”)和>>操作符(输入,或称“提取”)来代替C语言中的putchar()和getchar()函数

cout << "the value is " << i << endl;

13. 多态–运行时绑定

多态:一个函数或者操作符只有一个名字,但是他可以用于几个不同的派生类型的能力。每个对象都实现该操作的一种变型,变现一种最适合自身的行为。

class Fruit
{
    public : 
        peel() {printf("peeling a base class fruit\n");}
        slice();
        juice();
    private:
        int weight, 
        calories_per_oz;
};
//声明和调用
Fruit banana;
banana.peel();
//输出一个消息
peeling a base class fruit

class Apple :public Fruit
{
    public : 
    void peel(){printf("peeling an apple\n");}
    void make_candy_apple(float weight);
};

//声明和调用
fruit *p;
p = new apple;
p->peel();
peeling a base class fruit

14. 解释

出现上面这个结果的原因是:当派生类的成员函数取代基类的同名函数时,c++要求你必须预先通知编译器。通知的方法就是在可能被取代的基类成员函数面前加上virtual关键字

15. c++如何表现多态

#include "stdio.h"

class Fruit
{
public:
    virtual void peel()
    {
        printf("peeling a base fruit\n");
    }
private:
    int weight, calories_per_oz;
};

class Apple: public Fruit
{
public :
    void peel()
    {
        printf("peeling an apple\n");
    }
};

int main()
{
    Fruit *fruit = new Apple;
    fruit->peel();
}

运行结果:peeling an apple

结果可以在编译是获得,多态是一种运行时效果。它是指c++对象在运行时决定应该调用那个函数来实现某个特定操作的过程。

16. 多态


#include "stdio.h"

class Fruit
{
public:
    virtual void peel()
    {
        printf("peeling a base fruit\n");
    }
private:
    int weight, calories_per_oz;
};

class Apple: public Fruit
{
public :
    void peel()
    {
        printf("peeling an apple\n");
    }
};

int main()
{
    Apple apple;
    Fruit fruit;

    Fruit *p;

    p = &fruit;
    p->peel();

    p = &apple;
    p->peel();
}
运行结果:
    peeling a base fruit
    peeling an apple
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值