c++中虚拟静态函数的替代方案
Alternative to virtual static functions in c++?
在头文件。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*/)
我知道,抽象方法可以像下面这样在基类中定义,然后在派生类中定义:
在头文件。hpp:
class Base{
public:
virtual /*Some Return Type*/ func(/*Some Datatype*/) const = 0;
}
但是问题是虚方法需要对象实例化,这不是我想要的。我想在不创建对象的情况下调用方法。如果允许使用虚拟静态方法,它们就可以达到目的。
我能想到的唯一替代方案是在头文件中的所有派生类中声明函数func()
,并从基类中删除它。有没有别的方法可以做这件事?所以声明只在基类中一次,所有派生类只需要定义它们,而不需要重新声明?
调用不带对象的虚函数是逆向的,因为分辨率取决于对象的类型。您是否需要调用相同的函数依赖于对象的类型,或者指定类显式地,不带对象。这很容易通过使用两个函数,一个是静态的,一个是虚函数。(通常情况下,虚拟的只会转发给静态的)
编辑:
一个简单的例子(来自实际代码):
#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() ) ...
)我们已经建立了一个规则,只有这样你才能获得类的名称是通过使用这些函数之一来确定的。那有效地内部化了类的名称,并允许简单的指针比较工作。在我们的系统上这一点很重要)
你可以做得有点粗糙=)
//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:很奇怪,你不想在派生类中声明这个函数,因为当你使用虚函数时,你应该在派生类
一种可能性是只在派生类中定义它们:
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或类型特征来寻找替代方法。
相关文章:
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- 检查编译时是否存在静态函数
- 名称隐藏对静态函数继承的实例使用
- 如果 C 函数仍然可以间接执行(通过回调函数),那么将它声明为静态函数是否是一种不好的做法?
- 类中静态函数C++意外结果
- 在工人类中使用不同类的静态函数进行实验
- 类 Referention 中C++回调函数引用非静态函数
- 指向模板上下文中的成员函数或静态函数的指针
- 如何检测 Clang AST C++中的静态函数
- 内联asm编译器屏障(内存阻塞器)是算作外部函数,还是算作静态函数调用
- 如何在静态函数中使用成员函数数组
- (2 问题)"类"类型重新定义(即使 #pragma 一次),以及静态函数内的静态成员对象初始化?
- 生成代码(在编译时)以调用模板的每个实例化的静态函数
- C++无法访问或使用静态函数
- 如何将 cpp 文件中的静态函数公开给其他文件
- 将函数的引用设置为其他 c++ 文件中的非静态函数
- 方法的静态函数的等价性
- 扩展包含静态函数的类
- 非静态函数可以访问静态变量吗?
- c++中虚拟静态函数的替代方案