【问题标题】:C++ virtual variable in inheritance class hierarchy继承类层次结构中的 C++ 虚拟变量
【发布时间】:2013-08-27 13:50:56
【问题描述】:

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

                   ___ Class (ClassA)
                  |
AbstractClass_____

                  |___ Class (ClassB)

在 classA 和 ClassB 中,我有一个模板类型的 const NullPosition,这在 ClassA 和 ClassB 中是不同的。在 classA 和 ClassB 中,我必须执行一些取决于 NullPosition 值的操作。

现在我需要根据 NullPosition 上的值进行一些操作,但是我很难,因为变量是不同的类型和值。更具体地说,classA 中的 NullPosition 标识无效的数组索引,因此等于 -1; 在 classB 中,它标识一个 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 "Class/ClassA/Class.h" for classA 和 #include " ClassB 的 Class/ClassB/Class.h"。

【问题讨论】:

  • 是不是只有我一个人在读完最后一段后脊背发凉?
  • 我对您所做的一些选择有很多疑问,这似乎使这更加混乱。为什么不用template &lt;class Type, class Position&gt; 而不是typedef T Type
  • 子类中无法访问模板参数名称。
  • 为 WhozCraig 的颤抖添加一些背景:你为什么要这样做?您已经可以互换使用它们,而不包括使用指向它们的基类的指针的废话,至少如果它们都派生自某个 AbstractClass。如果 ClassA 和 ClassB(即派生最多的类型)不同但仍可互换使用,您可能需要检查您的设计是否存在缺陷或提供转换。否则,如果需要ClassA,请使用ClassA,如果需要ClassB,请使用ClassB。对不同的类型使用相同的名称是非常有害的。

标签: c++ templates variables virtual


【解决方案1】:

我没有看到问题。你有很多选择:

  • 将 NullPosition 作为非类型模板参数传递给基类。
  • 创建一个特征类来确定某些类型的空位置。在定义子类之前对其进行专门化。
  • 将抽象函数添加到子类覆盖的基类以返回空位置。
  • 将抽象函数添加到子类覆盖的基类以确定位置是否为 NullPosition。

【讨论】:

    【解决方案2】:

    我不确定我是否理解整个要求,但您似乎正在尝试在 MethodX 上做一些不同的事情,具体取决于 P 的类型。

    您可以对 MethodX 函数等使用模板特化,因为两个派生类的第二个参数 P 不同。

    类似这样的:

    template<class T> void MethodX<T,NullPosition>
    {
        // Do NullPosition stuff here
    }
    

    【讨论】:

      【解决方案3】:

      也许有什么我不明白的,但是如果你需要一个父类中的成员,那为什么把它放在子类而不是父类中呢?

      哦,如果你有两个同名但方法实现不同的类,那么链接后只会存在其中一个方法。如果您想在不同的源文件中使用通用名称访问这两个类,请使用 typedefs:

      class foo1 {.....};
      class foo2 {.....};
      
      typedef foo foo1;
      // or typedef foo foo2;
      

      【讨论】:

        猜你喜欢
        • 2012-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-22
        • 1970-01-01
        • 1970-01-01
        • 2021-03-08
        • 2011-06-16
        相关资源
        最近更新 更多