在运用C++模板时,通常会遇到类模板的声明和实现如何分离的问题。本人在学习C++数据抽象和问题求解时,也曾遇到过这类问题。现在说明如何解决这个问题,这里采用的例子是基于数组实现一个栈,具体实现思路是建立一个抽象类CStackIterface,然后由类CArrayStack继承并实现。
除了让类模板的声明和实现放在同一个头文件中,还可以将其分离。具体做法是,在main()函数所在的cpp文件,引入类模板的cpp实现文件,即#include ''CArrayStack.cpp'',而不是头文件。在这个例子中,main.cpp主要包含的是测试代码,测试实现的栈是否正确。具体代码如下,代码可在后面下载。
此处为CStackIterface.h文件:
/**@file JStackInterface.h */
#ifndef CStack_Interface_160815_H //此处为预编译指令,为避免出现重定义问题
#define CStack_Interface_160815_H
#include<vector>
using namespace std; //此处要加这一句,否则会出现很多错误
template<class ItemType>
class CStackInterface
{
public:
/** Sees whether this stack is empty.
@return True if the stack is empty,or false if not.*/
virtual bool isEmpty() const=0;
/** Adds a new entry to the top of the stack.
@post If the operation was successful,newEntry is at the top of the stack.
@param newEntry The object was to be added as a new entry.
@return True if the addition is successful or false if not.*/
virtual bool push(const ItemType& newEntry)=0;
/** Remove the top of the stack.
@post If the operation was successful,the top of the stack has been removed.
@return True if the removal is successful or false if not.*/
virtual bool pop()=0;
/** Returns the top of the stack.
@pre The stack is not empty.
@post The top of the stack has been returned,and the stack is unchanged.
@return The top of the stack.*/
virtual ItemType peek() const =0;
/** Counts the number of the stack.
@return The number of the stack.*/
virtual int getItemCount() const=0;
/** Empties and then fills a given vector with all entries that are in this stack.
@return A vector containing all the entries in the stack.*/
virtual vector<ItemType> toVector() const=0;
};
#endif
此处为CArrayStack.h
/** ADT stack:Array based implementation: @file CArrayStack.h */
#ifndef CArray_Stack_160815_H_ //此处为预编译指令,为避免出现重定义问题
#define CArray_Stack_160815_H_
#include "CStackInterface.h"
template<class ItemType>
class CArrayStack:public CStackInterface<ItemType>
{
private:
static const int MAX_STACK=6;
ItemType items[MAX_STACK];
int top;
public:
CArrayStack();
bool isEmpty() const;
bool push(const ItemType& newEntry);
bool pop();
ItemType peek() const;
int getItemCount() const;
vector<ItemType> toVector() const;
~CArrayStack();
};
//这里不加#include "CArrayStack.cpp"
//在C++数据抽象和问题求解中,在此处有这个,但是编译不通过,将其加在main()所在的cpp文件中,编译通过
#endif
此处为CArrayStack.cpp文件
/** @file CArrayStack.cpp*/
#include<cassert>
#include "CArrayStack.h"
using namespace std;
template<class ItemType>
CArrayStack<ItemType>::CArrayStack():top(-1) //using initiator
{
}
template<class ItemType>
bool CArrayStack<ItemType>::isEmpty() const
{
return top<0;
}
template<class ItemType>
bool CArrayStack<ItemType>::push(const ItemType& newEntry)
{
bool result=false;
if (top<MAX_STACK)
{
top++;
items[top]=newEntry;
cout<<"Push is successful.\n";
result=true;
}
return result;
}
template<class ItemType>
bool CArrayStack<ItemType>::pop()
{
bool result=false;
if (!isEmpty())
{
top--;
cout<<"Pop is successful.\n";
result=true;
}
return result;
}
template<class ItemType>
ItemType CArrayStack<ItemType>::peek() const
{
assert(!isEmpty());
return items[top];
}
template<class ItemType>
int CArrayStack<ItemType>::getItemCount() const
{
if (!isEmpty())
return top+1;
else
return 0;
}
template<class ItemType>
vector<ItemType> CArrayStack<ItemType>::toVector() const
{
vector<ItemType> stackContent;
for (int i=0;i<top;i++)
{
stackContent.push_back(items[i]);
}
return stackContent;
}
template<class ItemType>
CArrayStack<ItemType>::~CArrayStack()
{
cout<<"Destruction function was called.\n";
}
此处为main.cpp文件(main()所在文件)
#include<iostream>
#include<string>
#include<exception>
#include "CArrayStack.cpp" //这里不引用CArrayStack.h文件
using namespace std;
int main()
{
CArrayStack<string>* stackPtr=new CArrayStack<string>();
string ch;
if (stackPtr->isEmpty())
cout<<"Empty Stack.\n";
cout<<"Enter six strings:\n";
cin>>ch;
int i=0;
while (cin && i<6)
{
stackPtr->push(ch);
cout<<"The top is: "<<stackPtr->peek()<<endl;
cin>>ch;
i++;
}
cout<<"The number of the stack: "<<stackPtr->getItemCount()<<endl;
for (int j=0;j<6;j++)
{
cout<<"The top is: "<<stackPtr->peek()<<endl;
cout<<"The number of the stack: "<<stackPtr->getItemCount()<<endl;
stackPtr->pop();
if (stackPtr->isEmpty())
cout<<"Stack now is Empty.\n";
}
if (stackPtr !=NULL)
{
delete stackPtr;
stackPtr=NULL;
}
cout<<"Finished!\n";
return 0;
}
由于本人能力所限,有很多不足,希望能够理解。