C++ 第15章 面向对象程序设计(一)

面向对象的程序设计(OPP)

面向对象设计的核心思想就是数据抽象、继承和动态绑定。通过抽象我们可以将类的接口与实现分离;使用继承,可以定义相似的类型并对其相似关系建模;使用动态绑定,可以在一定程度上忽略相似类型的区别,而以统一的方式使用它们的对象。

继承

通过继承联系在一起的类构成一种层次关系,通常在层次关系的根部有一个基类,其他类则直接或间接的从基类继承而来,这些继承得到的类为派生类。

基类负责定义在层次关系中所有类共同拥有的成员,每个派生类定义各自特有的成员。

基类将类型相关的函数与派生类不做改变直接继承的函数区分对待,对于某些函数,基类希望它的派生类各自定义适合自身的版本,此时基类就将这些函数声明为虚函数。

class Quote
{
    public:
        std::string isbn() const;
        virtual double net_price(std::szie_t n) const;
};

派生类必须通过使用派生列表明确指出它是从哪个基类继承而来,类派生列表的形式是:首先一个冒号,后面紧跟以逗号分隔的基类列表,其中每个类前面可以有访问说明符:

class Bulk_quote:public Quote
{
    public:
        double net_price(ste::size_t) const override;
};
派生类必须在其内部对所有重新定义的虚函数进行声明,可以在这样的函数之前加上virtual关键字,
也可以在形参列表之后加上override关键字。

动态绑定

通过动态绑定,我们能使用同一段代码分别处理Quote和Bulk_quote对象。

double print_total(ostream &os,const Quote &item,size_t n)
{
    double ret = item.net_price;
    os<<"ISBN:"<<item.isbn()<<"#sold:"<<n<<"total due"<<ret<<endl;
    return ret;
}
//根据传入形参的格式选择调用Quote::net_price或者Bule_quote::net_preice

protected说明符和private的区别:

派生类和类的成员函数以及友元函数可以访问protected成员,而private成员可以被类的成员函数以及友元函数访问,而派生类的成员函数却无权访问。

类型转换与继承

静态类型与动态类型

当我们使用存在继承关系的类型的时候,必须将一个变量或其他表达式的静态类型与该表达式表示对象的动态类型区分开来。

不存在从基类向派生类的隐式转换,在对象之间不存在类型转换

当我们使用一个派生类对象为一个基类对象初始化或者赋值时,只有该派生类对象中的基类部分会被拷贝、移动或赋值,它的派生类部分将被忽略掉。

//
静态类型与动态类型
静态类型是指编译时已知的,变量声明时的类型或者表达式生成的类型。
动态类型是指变量或表达式表示的内存中的对象的类型,运行时才知道。

虚函数

当我们使用基类的引用或指针调用一个虚函数时会执行动态绑定,因为直到运行时才会知道调用了哪个版本的虚函数,所以所有的虚函数必须都有定义。

//
struct B
{
    vitrual void f1(int) const;
    vitural void f2() const final;
};
struct D1:B
{
    void f1(int) const override;
};

//
override 在C++11中可以使用override关键字来说明派生类中的虚函数
final 如果我们把函数定义成final,则之后的任何尝试覆盖该函数的操作都将引发错误

虚函数也可以拥有默认实参。如果某次函数调用了默认实参,则该实参值由本次调用的静态类型决定。

如果虚函数使用默认实参,则基类和派生类中定义的默认实参最好一致。

//强行调用基类中定义的函数版本而不管baseP的动态类型到底是什么。
double undiscounted = baseP->Quote::net_price(42);
通常情况下只有成员函数(或友元)中的代码才需要使用作用域运算符来回避虚函数机制

不能继承友元关系,每个类负责控制各自成员的访问权限。

class Base
{
public:
    std::size_t size() const { return n; }
protected:
    std::size_t n;    
};

class Derived : private Base
{
public:
    using Base::size;
protected:
    using Base::n;
};
通过在类的内部使用uisng声明语句,我们可以将该类的直接或者间接基类中的任何可访问成员标记出来。

派生类只能为那些它可以访问的名字提供using声明。

一个私有派生的类最好显示的将private声明出来。

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值