C++ Primer Plus学习笔记之C++中的代码重用

前言

个人觉得学习编程最有效的方法是阅读专业的书籍,通过阅读专业书籍可以构建更加系统化的知识体系。
一直以来都很想深入学习一下C++,将其作为自己的主力开发语言。现在为了完成自己这一直以来的心愿,准备认真学习《C++ Primer Plus》。
为了提高学习效率,在学习的过程中将通过发布学习笔记的方式,持续记录自己学习C++的过程。

一、包含对象成员的类

valarray类是由头文件valarray支持的。这个类用于处理数值(或具有类似特性的类),它支持诸如将数组中所有元素的值相加以及在数组中找出最大和最小的值等操作。valarray被定义为一个模板类,以便能够处理不同的数据类型。
使用valarray类来声明一个对象时,需要在标识符valarray后面加上一对尖括号,并在其中包含所需的数据类型:

valarray<int> q_values;

通常,用于建立has-a关系的C++技术是组合(包含),即创建一个包含其他类对象的类。

二、私有继承

私有继承是C++实现has-a关系的另一种途径。使用私有继承,基类的公有成员和保护成员都将成为派生类的私有成员。这意味着基类方法将不会成为派生对象公有接口的一部分,但可以在派生类的成员函数中使用它们。
要进行私有继承,请使用关键字private而不是public来定义类(实际上,private是默认值,因此省略访问限定符也将导致私有继承)。

Class Student : private std::string, private std:: valarry<double>
{
    ...
};

使用多个基类的继承被称为多重继承(multiple inheritance,MI)。

通常,应使用包含来建立has-a关系;如果新类需要访问原有类的保护成员,或需要重新定义虚函数,则应使用私有继承。

保护继承是私有继承的变体。保护继承在列出基类时使用关键字protected

class Student : protected std:string, protected std::valarry<double>
{
    ...
};

使用私有继承时,第三代类将不能使用基类的接口,这是因为基类的公有方法在派生类中变成了私有方法;使用保护继承时,基类的公有方法在第二代类中将变成受保护的,因此第三代派生类可以使用它们。

各种继承方式:

特征公有继承保护继承私有继承
公有成员变成派生类的公有成员派生类的保护成员派生类的私有成员
保护成员变成派生类的保护成员派生类的保护成员派生类的私有成员
私有成员变成只能通过基类接口访问只能通过基类接口访问只能通过基类接口访问
能否隐式向上转换是(但只能在派生类中)

可以使用using重新定义访问权限,指出派生类可以使用特定的基类成员,即使采用的是私有派生。

Class Student : private std::string, private std:: valarry<double>
{
...
public:
    using std:: valarry<double>::min;
};

上述using声明使得valarry<double>::min可用,就像他们是Student的公有方法一样。
注意using声明只使用成员名——没有圆括号、函数特征标和返回类型。

三、多重继承

C++引入多重继承的同时,引入了一种新技术——虚基类(virtual base class)。

class marketing : public virtual reality { ... };

多重继承会增加编程的复杂程度。这种复杂性主要是由于派生类通过多条途径继承同一个基类引起的。

四、类模板

C++的类模板为生成通用的类声明提供了一种更好的方法。

模板类以下面这样的代码开头(较新的C++实现允许使用typename代替class):

template <class Type>

类模板可以为类型参数提供默认值:

template <class T1, class T2 = int> class Topo { ... };

这样,如果省略T2的值,编译器将使用int

由于模板不是函数,它们不能单独编译。模板必须与特定的模板实例化请求一起使用。为此,最简单的方法是将所有模板信息放在一个头文件中,并在要使用这些模板的文件中包含该头文件。

仅在程序包含模板并不能生成模板类,而必须请求实例化。为此,需要声明一个类型为模板类的对象,方法是使用所需的具体类型替换泛型名。

Stack<int> ker;
Stack<double> co;

看到上述声明后,编译器将按照Stack<Type>模板来生成两个独立的类声明和两组独立的类方法。
泛型标识符——例如这里的Type——被称为类型参数(type parameter),这意味着它们类似于变量,但赋给它们的不能是数字,而只能是类型。

可以将内置类型或类对象用作类模板Stack<Type>,但如果使用指针,在不对程序做重大修改的前提下,将无法很好的工作。

可以使用typedef为模板具体化指定别名:

typedef std::array<double, 12> arrd;
arrd gallons;//gallons的类型为std::array<double, 12>

C++新增了一项功能——使用模板提供一系列别名:

template<typename T>
using arrtype = std::array<T, 12>;

这将arrtype定义为一个模板别名,可以使用它来指定类型:

arrtype<double> gallons;

C++11允许将语法using=用于非模板,这时与常规typedef等价:

using pc2 = const char *;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值