继承类层次结构中的C++虚拟变量



我有一个模板类层次结构,

                   ___ 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;

最新更新