我有一个模板类层次结构,
___ Class (ClassA)
|
AbstractClass_____
|___ Class (ClassB)
在classA和ClassB中,我有一个模板化类型的常量NullPosition,这在classA与ClassB中是不同的。在classA和ClassB中,我必须执行一些依赖于NullPosition值的操作。
现在,我需要根据NullPosition上的值进行一些操作,但由于变量的类型和值不同,我遇到了困难。更具体地说,类A中的NullPosition标识无效的数组索引,因此等于-1;在类B中,它标识一个NULL指针,因此它等于0。
请在下面找到一个例子。
#ifndef ABSTRACTCLASS_H
#define ABSTRACTCLASS_H
template <class T, class P>
class AbstractClass
{
public:
typedef T Type;
typedef P Position;
void MethodX() const;
virtual Position Method() const = 0;
};
template <class T, class P>
void AbstractClass<T,P>::MethodX() const
{
Position p=Method();
/*
what I am trying to achieve is being able to use the constant NullPosition in abstract class.
if (p==NullPosition)
cout<<"p is equal NULLPOSITION";
else
cout<<"p is not equal NULLPOSITION";
*/
}
#endif
#ifndef CLASS_A_H
#define CLASS_A_H
#include "../AbstractClass.h"
template <class T>
class Class:public AbstractClass<T,unsigned int>
{
public:
typedef T Type;
typedef typename AbstractClass<T,unsigned int>::Position Position;
Class();
Position Method() const;
static const Position NullPosition=-1;
private:
Type* TypeArray;
unsigned int nElements;
};
template <class T>
Class<T>::Class()
{
nElements=0;
TypeArray=new Type[128];
}
template <class T>
typename Class<T>::Position Class<T>::Method() const
{
return NullPosition;
}
#endif
#ifndef CLASS_B_H
#define CLASS_B_H
#include "../AbstractClass.h"
template <class T>
struct elementNode
{
typedef T Type;
typedef elementNode* Position;
Type element;
Position nextNode;
};
template <class T>
class Class:public AbstractClass<T, typename elementNode<T>::Position>
{
public:
typedef T Type;
typedef typename AbstractClass<T, typename elementNode<T>::Position>::Position Position;
Class();
Position Method() const;
static const Position NullPosition;
private:
Position root;
Position lastElement;
};
template <class T>
const typename Class<T>::Position Class<T>::NullPosition=0;
template <class T>
Class<T>::Class()
{
lastElement=root=NullPosition;
}
template <class T>
typename Class<T>::Position Class<T>::Method() const
{
return NullPosition;
}
#endif
#include <cstdlib>
#include <iostream>
using namespace std;
#include "Class/ClassA/Class.h"
int main(int argc, char *argv[])
{
Class<int> classA;
classA.MethodX();
system("PAUSE");
return EXIT_SUCCESS;
}
请不要让ClassA和ClassB共享相同的名称Class,这样我就可以通过更改include路径在代码中互换使用它们——#include"Class/ClassA/Class.h"代表ClassA,#include"Class/ClassB/Class.h"代表ClassB。
我看不出问题。你有很多选择:
- 将NullPosition作为非类型模板参数传递给基类
- 创建一个traits类,用于确定某个类型的null位置。在定义子类之前对其进行专门化
- 向基类添加一个抽象函数,子类覆盖该函数以返回null位置
- 向基类添加一个抽象函数,子类覆盖该函数以确定某个位置是否为NullPosition
我不确定我是否理解整个需求,但根据p的类型,您似乎正在尝试在MethodX上做一些不同的事情。
您可以对MethodX函数等使用模板专用化,因为第二个参数p对于两个派生类是不同的。
类似这样的东西:
template<class T> void MethodX<T,NullPosition>
{
// Do NullPosition stuff here
}
也许有一些我不理解的地方,但如果你需要父类中的成员,为什么要把它放在子类中而不是父类中?
哦,如果您有两个名称相同但方法实现不同的类,那么链接后只会存在其中一个方法。如果您想在不同的源文件中使用一个通用名称访问这两个类,请使用typedefs:
class foo1 {.....};
class foo2 {.....};
typedef foo foo1;
// or typedef foo foo2;