第14章——C++的代码重用
来源:互联网 发布:抓包软件有哪几种 编辑:程序博客网 时间:2024/06/05 11:07
C++的一个主要目标是促进代码重用。公有继承是实现这种目标的机制之一,但并不是惟一的机制。还有包含,私有继承和保护继承。通常他们是用来实现has-a关系。
l 包含对象的类
就是类的成员本身又是另外一个类的对象。
eg:
class student
{
private:
string name;
valarray<double> scores;
……
};
student类获得了其成员对象的实现,但没有继承其接口。即student类中的string类和valarray<double>类的方法可以在student类方法实现中使用,但在student外部,不能使用string类和valarray<double>类的方法。
对其构造函数的实现:
student(const char *str,const double *pd,int n)
:name(str),scores(pd,n){}
构造函数初始化的是成员对象,而不是继承的对象,所以在初始化列表中使用的是成员名,而不是类名。
对于继承的对象,构造函数在成员初始化列表中使用类名来调用特定的基类构造函数。对于成员对象,构造函数使用成员名。
l 私有继承
使用私有继承,基类的公有成员和保护成员都将为派生类的私有成员。这意味着基类方法将不会成为派生对象公有接口的一部分,但可以在派生类的成员函数中使用它们。
eg:
class student:private std::string,private std::valarray<double>
{
public:
…
};
要执行私有继承,请使用关键字private。实际上,private是默认值,因此省略访问限定符也将导致私有继承。
私有继承的构造函数
student(const char *str,const double *pd,int n)
:std::string(str),ArrayDb(pd,n){}
使用包含时将使用对象名来调用方法,而使用私有继承时将使用类名和作用哉解析操作符来调用。
使用保护继承时,基类的公有成员和保护成员都将成为派生类的保护成员。使用私有继承时,第三代类将不能使用基类的接口,而保护继承时,第三代类可以使用。
在保护派生或私有派生时,要让基类的方法在派生类外面可用,有两种方法
1. 定义一个使用该基类方法的派生类方法
2. 使用一个using声明
eg:
class student:private std:string,private std::valarray<double>
{
public:
using std::valarray<double>::min;
using std::valarray<double>::max;
…
};
using声明只适用于继承,而不适用于包含。
l 多重继承
MI描述的是有多个直接基类的类。
MI可能给程序员带来两个主要的问题:1.从两个不同的基类继承同名方法 2.从两个或更多相关基类那里继承同一个类的多个实例。
类限定符可以解决名称二义性问题,引用虚基类来避免继承多个基类对象的问题。
cass singer:virtual public worker{…};
cass waiter:virtual public worker{…};
class singingwaiter:public singer,public waiter{…};
worker被用作singer和waiter的虚基类。singingwaiter对象将只包含worker对象的一个拷贝。
MI的构造函数
singingwaiter(const worker &wk,int p=0,int v= singer::other)
:worker(wk),waiter(wk,p),singer(wk,v){}
上述代码显式调用构造函数 worker(const worker &)。对于虚基类,必须这样做,对于非虚基类,则是非法的。
l 类模板
模板,接受的参数是类型。
类模板和函数模板开头都有template <class Type>或template <typename Type>
类模板就是前面的声明,再加上类中被Type取代的具体类型。因为模板不是函数,它们必须与特定的模板实例化请求一起保用。
eg:
template <class Type>
class Stack
{
private:
enum {MAX = 10}; // constant specific to class
Type items[MAX]; // holds stack items
int top; // index for top stack item
public:
Stack();
bool isempty();
bool isfull();
bool push(const Type & item); // add item to stack
bool pop(Type & item); // pop top into item
};
模板类中的方法定义前都要加上
template <class type>,而且方法名前加限定符
eg:
template <class Type>
Stack<Type>::Stack()
{
top = 0;
}
指针也可以是用作模板处理的类型。模板可以有多个参数,参数可以是类型参数,也可以是非类型参数。类模板中可以给类型参数和非类型参数提供默认值,函数模板只能给非类型参数提供默认值。
模板可以被显式实例化
template class ArrayTP<string,100>
模板具体化
template <> class sortedarray<char *>{…};
模板可用作结构、类或模板类的成员。
模板用作参数
template <template <typename T> class Thing>
class crab
{
private:
Thing<int> s1;
Thing<double> s2;
……
};
模板参数是template <typename T> class。这意味着s1是一个类,这个类用template <typename T>这个模板进行隐式实例化。T为int.
模板类和友元
非模板友元
template <class T>
class HasFriend
{
friend void counts();
friend void report(HasFriend<T> &);
…
};
以上类中counts()和reports()函数并不是模板函数,当模板当实例成doulbe和int类型时,
counts()和reports()的定义
void counts()
{
cout<<”int count: ”<<HasFriend<int>::ct<<”;”;
cout<<”double count: ”<<HasFriend<double>::ct<<”;”;
}
void reports(HasFriend<int> &hf)
{
cout<<” HasFriend<int>: ”<<hf.item<<endl;
}
void reports(HasFriend<double> &hf)
{
cout<<” HasFriend<double>: ”<<hf.item<<endl;
}
模板类的约束模板友元函数
包含3步:
1. template <typename T> void counts();
template <typename T> void reports(T &);
2. 在类中声明
template <typename TT>
class HasFriend
{
friend void counts<TT>();
friend void report<>(HasFriend<T> &);
…
};
counts()函数没有参数,所以必须显式具体化。所以在friend前可有template<>
reports()后<>为空,因为它有参数,可被它有函数参数来确定模板类型参数。
3.模板定义
非约束模板友元函数
通过在类内部声明模板,可以创建非约束码元函数
template <typename T>
class ManyFriend
{
template <typename C,typename D> friend void show2(C&,D&);
…
};
调用:
ManyFriend<int> hfi1(10);
ManyFriend<int> hfi2(20);
show2(hfi1,hfi2);
- 第14章——C++的代码重用
- 第14章 代码重用
- 第14章 C++代码重用
- 第14章-C++中的代码重用
- C++ Primer Plus 第14章 C++中的代码重用
- C++ Primer Plus -- 第14章 C++的代码重用 笔记
- 《php和mysql web开发》笔记——第5章 代码重用与函数编写
- 不要重复发明轮子:C++重用的5重境界(1)——代码重用
- 提高代码的重用性之——泛型
- C++ Primer-学习笔记#1 第14章_C++中的代码重用
- C++学习笔记(第14章->代码重用->包含,继承,多重继承,虚基类)
- C++学习笔记(第14章->代码重用->类模板)
- 【读书笔记:C++ primer plus 第六版 中文版】第14章 C++中的代码重用
- 《Object-Oriented Programming With ANSI-C》之第四章(继承——代码重用和改进)
- 第十四章:C++的代码重用
- Cell的重用代码
- c++的代码重用
- UITableViewCell的重用代码
- Hadoop0.21.0源码编译流程
- 内建函数
- 绑定网关mac地址防止arp攻击
- Android核心分析
- matlab code snippet #3
- 第14章——C++的代码重用
- 使用JDBC如何获取数据库自动生成的主键
- Java编程解析节省内存效率高的方法
- 5.3例题--日历问题--2964
- 最近时间安排
- Sqlserver 游标 慢
- Evernote推出Clearly:让您享受阅读(含视频)
- 前端脚本爱好者
- python 解码js escape,encodeURI