我有一个c++类,它的部分定义是:
template <class InputClass>
class MyClass
并且InputClass
被定义为MyClass:的子类
class InputClass: public MyClass<InputClass>
MyClass中有很多地方有这个调用:
InputClass::AttributeName()
其中AttributeName()
在InputClass的不同子类上定义为:
static std::string AttributeName
然而,最近,InputClass有一个特定的子类,我们必须将attributeName定义为非静态的,因为我们希望这个新子类的不同实例不共享AttributeName
(:
std::string AttributeName
我可以做什么修改,以便从MyClass
内部仍然可以将AttributeName()
作为静态或非静态变量?
老实说,我不知道如何在派生类中使静态和非静态成员函数具有相同的名称,并在基类中区分它们。此外,我不知道是否有一种方法可以调用在派生类中声明而不在基类中声明的非静态成员函数。
如果我们省略了这两个要求,那么您可以检查静态函数是否存在并调用它,或者回退到非静态(虚拟(函数(在我的示例中,我将静态和非静态函数的AttributeName
函数替换为static_name
和name
(:
#include <string>
#include <iostream>
#include <utility>
#include <experimental/type_traits>
template<class InputClass>
class Item {
virtual std::string name() {
return "none";
};
...
public:
virtual ~Item() = default;
...
};
class DerivedNonStatic: public Item<DerivedNonStatic> {
std::string name() final {
return "non-static item";
}
};
class DerivedStatic: public Item<DerivedStatic> {
public:
static std::string static_name() {
return "static item";
}
};
现在,在基本的Item
类中,您可以决定使用哪个函数,如下所示:
class Item {
template<typename T>
using static_name_t = decltype(T::static_name); // static member function type
static constexpr bool has_static_name = std::experimental::is_detected_v<static_name_t, InputClass>;
void printName() {
if constexpr(has_static_name) {
std::cout << InputClass::static_name() << std::endl;
} else {
std::cout << this->name() << std::endl;
}
};
...
}
以及如何在客户端代码中使用:
int main() {
DerivedNonStatic dns;
dns.printName(); // prints "non-static item"
DerivedStatic ds;
ds.printName(); // prints "static item"
}