C++ 虚拟静态变量

C++ 虚拟静态变量,c++,c++11,C++,C++11,我需要为类Base的每个子体指定唯一的整数值,这些子体应该可以通过使用指向这些类或其类型名的指针来访问 我是这样实施的 class Base { public: int idCompType = InvalidCompType; virtual int getCompType() = 0; } 然后在base的每个子代中,我应该声明idCompType(对于模板)并重写getCompType(对于指针): 现在我可以从指针到基找到comp类型 Base *comp = getComp(

我需要为类Base的每个子体指定唯一的整数值,这些子体应该可以通过使用指向这些类或其类型名的指针来访问

我是这样实施的

class Base {
public:
  int idCompType = InvalidCompType;
  virtual int getCompType() = 0;
}
然后在base的每个子代中,我应该声明idCompType(对于模板)并重写getCompType(对于指针):

现在我可以从指针到基找到comp类型

Base *comp = getComp(...);
std::cout << comp->getCompType();
Base*comp=getComp(…);
std::cout getCompType();
或在模板中使用typename:

template <typename T>
int getType() {
  return T::idCompType;
}
模板
int getType(){
返回T::idCompType;
}
在每个子类中没有双重声明idCompType和getCompType(),有没有办法使它更简单?在对象Pascal中,我使用虚拟静态方法实现了这一点,但是它们在C++ ++… PS:问题不在于虚拟静态方法——虚拟静态方法只是可能的解决方案之一,也是我用其他语言解决问题的方式。

我的建议:

对基础
的更改

class Base {
   public:

      virtual int getCompType() = 0;

   protected:

      static int getNextCompType()
      {
         static int nextType = 0;
         return ++nextType;
      }
 };
对派生类的更改:

class Real1: public Base {
   public:
  static int getCompTypeImpl()
  {
     static int myType = Base::getNextCompType();
     return myType;
  }

  int getCompType() override
  {
     return getCompTypeImpl();
  }
};
以下是一个工作程序:

#include <iostream>

class Base {
   public:

      virtual int getCompType() = 0;

   protected:

      static int getNextCompType()
      {
         static int nextType = 0;
         return ++nextType;
      }
 };

class Real1: public Base {
   public:

      static int getCompTypeImpl()
      {
         static int myType = Base::getNextCompType();
         return myType;
      }

      int getCompType() override
      {
         return getCompTypeImpl();
      }
};

class Real2: public Base {
   public:
      static int getCompTypeImpl()
      {
         static int myType = Base::getNextCompType();
         return myType;
      }

      int getCompType() override
      {
         return getCompTypeImpl();
      }
};

template <typename T> int getCompType()
{
   return T::getCompTypeImpl();
}

int main()
{
   Real1 v1;
   Real2 v2;

   std::cout << v1.getCompType() << std::endl;
   std::cout << v2.getCompType() << std::endl;

   std::cout << getCompType<Real1>() << std::endl;
   std::cout << getCompType<Real2>() << std::endl;
};
#包括
阶级基础{
公众:
虚拟int getCompType()=0;
受保护的:
静态int getNextCompType()
{
静态int nextType=0;
return++nextType;
}
};
类Real1:公共基{
公众:
静态int getCompTypeImpl()
{
静态int myType=Base::getNextCompType();
返回myType;
}
int getCompType()重写
{
返回getCompTypeImpl();
}
};
类Real2:公共基{
公众:
静态int getCompTypeImpl()
{
静态int myType=Base::getNextCompType();
返回myType;
}
int getCompType()重写
{
返回getCompTypeImpl();
}
};
模板int getCompType()
{
返回T::getCompTypeImpl();
}
int main()
{
Real1 v1;
real2v2;

std::cout这里是@Sahu版本的一个轻微变体。 不要在每个派生类中实现相同的
getCompTypeImpl()
,而是将其放在
Base
类中

template<typename T>
static int getCompTypeImpl()
{
    return getNextCompType<T>();
}   
最后介绍2个新的静态数据成员

private:
    static std::map<std::type_index, int> m_table;
    static int nextType;
private:
静态标准::映射m_表;
静态int-nextType;
请找到完整的代码

诚然,这引入了两个新的静态成员,并且做了更多的工作
与Sahu的原始版本相比。但是,这消除了实现中方法的负担

所有派生类。

@R Sahu答案的另一个变体是消除派生类中的代码重复:

#include <iostream>

class Base {
   public:
      virtual int getCompType() const = 0;

      template <typename T>
      static int getCompTypeOf()
      {
         static int compType = getNextCompType();
         return compType;
      }

   private:
      static int getNextCompType()
      {
         static int nextType = 0;
         return ++nextType;
      }
 };

template <typename Derived, typename DeriveFrom = Base>
class TypeAssigner : DeriveFrom {
   public:
      int getCompType() const override
      {
         return Base::getCompTypeOf<Derived>();
      }
};

class Real1: public TypeAssigner<Real1> {};

class Real2: public TypeAssigner<Real2> {};

class Real3 : public TypeAssigner<Real3, Real2> {};

int main()
{
   Real1 v1;
   Real2 v2;
   Real3 v3;

   std::cout << v1.getCompType() << '\n';
   std::cout << v2.getCompType() << '\n';
   std::cout << v3.getCompType() << '\n';

   std::cout << Base::getCompTypeOf<Real1>() << '\n';
   std::cout << Base::getCompTypeOf<Real2>() << '\n';
   std::cout << Base::getCompTypeOf<Real3>() << '\n';
};
#包括
阶级基础{
公众:
虚拟int getCompType()常量=0;
样板
静态int getCompTypeOf()
{
静态int compType=getNextCompType();
返回类型;
}
私人:
静态int getNextCompType()
{
静态int nextType=0;
return++nextType;
}
};
样板
类TypeAssigner:派生自{
公众:
int getCompType()常量重写
{
return Base::getCompTypeOf();
}
};
类Real1:公共类型赋值器{};
类Real2:公共类型赋值器{};
类Real3:公共类型赋值器{};
int main()
{
Real1 v1;
real2v2;
Real3 v3;

std::cout可能的重复您是否知道
typeid
&相关的机器,例如
std::type_index
?如果这是关于序列化的,请在Boost库中查找序列化支持。感谢您的回答,但在这里我可以看到相同的静态和虚拟方法的双重声明。您添加了自动id生成器离子..但我不需要它-我的ID保存在文件中,我需要手动调整them@Rem,您需要函数模板的静态函数和通过基类指针和引用使用它的虚拟函数。无法使用一组函数同时获得这两个功能。只有在他创建每个der的一个实例时,这才有效在这样一个像德尔菲这样的逆行语言中,我20年前当然可以做这件事……在现代C++中我不能做这件事真是很奇怪。14@EJP,不是真的。
static int myType=Base::getNextCompType();
在Impl()中函数确保返回相同的类型,即使为每个派生类创建了多个实例。
template<typename T>
static int getNextCompType()
{
    auto iter = m_table.find(std::type_index(typeid(T)));
    if (iter != m_table.end())
    {
        return iter->second;
    }
    else
    {
        m_table.insert(std::make_pair(std::type_index(typeid(T)), ++nextType));
        return nextType;
    }
}   
private:
    static std::map<std::type_index, int> m_table;
    static int nextType;
#include <iostream>

class Base {
   public:
      virtual int getCompType() const = 0;

      template <typename T>
      static int getCompTypeOf()
      {
         static int compType = getNextCompType();
         return compType;
      }

   private:
      static int getNextCompType()
      {
         static int nextType = 0;
         return ++nextType;
      }
 };

template <typename Derived, typename DeriveFrom = Base>
class TypeAssigner : DeriveFrom {
   public:
      int getCompType() const override
      {
         return Base::getCompTypeOf<Derived>();
      }
};

class Real1: public TypeAssigner<Real1> {};

class Real2: public TypeAssigner<Real2> {};

class Real3 : public TypeAssigner<Real3, Real2> {};

int main()
{
   Real1 v1;
   Real2 v2;
   Real3 v3;

   std::cout << v1.getCompType() << '\n';
   std::cout << v2.getCompType() << '\n';
   std::cout << v3.getCompType() << '\n';

   std::cout << Base::getCompTypeOf<Real1>() << '\n';
   std::cout << Base::getCompTypeOf<Real2>() << '\n';
   std::cout << Base::getCompTypeOf<Real3>() << '\n';
};