替代c ++中的虚拟静态函数?

时间:2013-04-04 15:14:53

标签: c++ oop inheritance static-methods virtual-method

在头文件.hpp中:

  class Base{
        public:
              static /*Some Return Type*/ func(/*Some Datatype*/);
  }    
  class Derived1 public Base{
        public: 
               Derived1();
               ~Derived1();
  }
  class Derived1 public Base{
        public: 
               Derived2();
               ~Derived2();
  }

在cpp文件中.cpp:

  /*Some Return Type*/ Derived1::func(/*Some Datatype*/){
  }

  /*Some Return Type*/ Derived2::func(/*Some Datatype*/){
  }

这显然失败了,因为无法覆盖子类中的静态方法。但是如何获得上述功能呢?

我必须打电话给这样的话:

  /*Some Return Type*/ result = Derived1::func(/*Some Datatype*/)
  /*Some Return Type*/ result = Derived2::func(/*Some Datatype*/)

我知道,抽象方法可以在基类中定义,如下所示,然后在Derived类中定义它们:

在头文件.hpp中:

  class Base{
        public:
              virtual /*Some Return Type*/ func(/*Some Datatype*/) const = 0;
  }  

但问题是虚方法需要对象实例化,这不是我想要的。我想在不创建对象的情况下调用该方法。如果允许使用虚拟静态方法,那么它们就可以达到目的。

我能想到的唯一选择是在头文件中的所有Derived类中声明函数func()并将其从Base类中删除。有没有其他方法可以做到这一点?因此声明在Base类中只有一次,并且所有Derived类只需要定义它们,而不是重新声明?

3 个答案:

答案 0 :(得分:4)

在没有对象的情况下调用虚函数是一种对比, 因为分辨率取决于对象的类型。 是您可能需要调用相同功能的情况 取决于对象的类型,或指定类 明确地,没有对象。这很容易通过使用来处理 两个函数,一个是静态的,一个是虚函数。 (通常, 虚拟的只会转发到静态。)

编辑:

一个简单的例子(来自实际代码):

#define DECLARE_CLASS_NAME(className)                               \
    static char className() { return STRINGIZE(className); }        \
    virtual char* getClassName() { return className(); }

class Base
{
public:
    DECLARE_CLASS_NAME(Base);
    //  ...
};

class Derived : public Base
{
public:
    DECLARE_CLASS_NAME(Derived);
    //  ...
};

等等,在所有派生类中。这习惯了 获取序列化的类型名称,例如:

std::string typeName = pObj->getClassName();

也是一个原始的RTTI(大约20年前):

if ( pObj->getClassName() == Derived::className() ) ...

(我们已经建立了唯一可以获得的规则 类的名称是使用这些函数之一。那 有效地内化了类的名称,并允许 简单的指针比较工作。在我们的系统上 那么,这很重要。)

答案 1 :(得分:1)

你可以这样做有点hacky =)

//header file
template<class T>
struct base_t
{
   static void do_smth();
};

struct derived1_t : base_t<derived1_t>
{

};

struct derived2_t : base_t<derived2_t>
{

};

//cpp file
void base_t<derived1_t>::do_smth() // `note base_t<derived1_t>::` instead of `derived1_t::`
{
   std::cout << "aaa" << std::endl;
}

PS:非常奇怪,你不想在派生类中声明这个函数,因为当你使用虚函数时,你应该在派生类中声明它们

答案 2 :(得分:1)

一种可能性是仅在派生类中定义它们:

  struct  Base
  {
      // nothing
  };

  struct Derived1 : public Base
  {
      static void func() { /*...*/ }
  };

  struct Derived2 : public Base
  {
      static void func() { /*...*/ }
  };

这允许您致电:

Derived1::foo();
Derived2::foo();

调用它作为基类型并期望编译器找出你所指的哪个子类型不能工作:

// How will the compiler know to choose 
// between Derived1:: func or Derived2:: func ?
Base::func(); 

您可能希望查看替代方法的CRTP或类型特征。