标签:
1、stack内存能否借助标准模板容器管理呢?答案是肯定的,只需要多传一个模板参数即可,而且模板参数还可以是缺省的,如下:
template <typename T, typename CONT = std::deque<T> > //此处末尾必须有空格,否则编译出错
class Stack
{
…
private:
CONT c_;
};
如果没有传第二个参数,默认为deque 双端队列,当然我们也可以传递std::vector<T>
2、示例:借助标准模板容器 deque 管理实现stack模板类
这里的Stack是适配器,STL六大组件之一,代码复用,不是通过继承;通过现有的类实现模板类
Stack.h:
#ifndef _STACK_H_
#define _STACK_H_
#include <exception>
#include <deque>
using namespace std;
template <typename T, typename CONT = deque<T> > //此处末尾必须有空格,否则编译出错
class Stack
{
public:
Stack() : c_()
{
}
~Stack()
{
}
void Push(const T &elem)
{
c_.push_back(elem);
}
void Pop()
{
c_.pop_back();
}
T &Top()
{
return c_.back();
}
const T &Top() const
{
return c_.back();
}
bool Empty() const
{
return c_.empty();
}
private:
CONT c_; //借助标准模板容器 deque 管理实现stack
};
#endif // _STACK_H_main.cpp:
#include "Stack.h"
#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
//Stack<int> s; //默认是deque实现
Stack<int, vector<int> > s;
s.Push(1);
s.Push(2);
s.Push(3);
while (!s.Empty())
{
cout << s.Top() << endl;
s.Pop();
}
return 0;
}
即如果没有传递第二个参数,堆栈和压栈等操作直接调用deque<int> 的成员函数,也由deque<int> 管理内存。
如程序中传递vector<int> ,则由vector<int> 成员函数处理。
来看下面的例子:
#include <iostream>
using namespace std;
template <typename T>
class MyClass
{
private:
T value;
public:
void Assign(const MyClass<T> &x)
{
value = x.value;
}
};
int main(void)
{
MyClass<double> d;
MyClass<int> i;
d.Assign(d); // OK
d.Assign(i); // Error
return 0;
}
#include <iostream>
using namespace std;
template <typename T>
class MyClass
{
private:
T value;
public:
MyClass() {}
template <class X>
MyClass(const MyClass<X> &x) : value(x.GetValue())
{
}
template <class X>
void Assign(const MyClass<X> &x)
{
value = x.GetValue(); //当不同类型时,value私用,应通过成员函数调用
}
T GetValue() const
{
return value;
}
};
int main(void)
{
MyClass<double> d;
MyClass<int> i;
d.Assign(d); // OK
d.Assign(i); // OK
MyClass<double> d2(i);
return 0;
}
#include <iostream>
using namespace std;
template <typename T>
class MyClass
{
private:
typename T::SubType* ptr_;
};
class Test
{
public:
typedef int SubType; //如果Test中没有定义SubType类型,则编译会失败
};
int main(void)
{
MyClass<Test> mc;
return 0;
}
(一)、派生类与模板
1、为了运行的效率,类模板是相互独立的,即独立设计,没有使用继承的思想。对类模板的扩展是采用适配器(adapter)来完成的(如之前使用deque实现Stack)。通用性是模板库的设计出发点之一,这是由泛型算法(algorithm)和函数对象(functor)等手段达到的。
2、派生的目标之一也是代码的复用和程序的通用性,最典型的就是MFC,派生类的优点是可以由简到繁,逐步深入,程序编制过程中可以充分利用前面的工作,一步步完成一个复杂的任务。
3、模板追求的是运行效率,而派生追求的是编程的效率。
(二)、面向对象与泛型编程
1、面向对象与泛型都依赖于某个形式的多态
(1)面向对象
(2)泛型动态多态(虚函数)
静态多态(模板类,模板函数)
2、面向对象中的多态在运行时应用存在继承关系。我们编写使用这些类的代码,忽略基类与派生类之间的类型差异。只要使用基类指针或者引用,基类类型对象、派生类类型对象就可以共享相同的代码。
3、在泛型编程中,我们所编写的类和函数能够多态地用于编译时不相关的类型。一个类或一个函数可以用来操纵多种类型的对象。
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
C++ Primer 学习笔记_45_模板(三):缺省模板参数(借助标准模板容器deque实现Stack模板)、成员模板、关键字typename
标签:
原文地址:http://blog.csdn.net/keyyuanxin/article/details/50667431