代码之家  ›  专栏  ›  技术社区  ›  user1008636

在c中处理静态和非静态函数++

c++
  •  0
  • user1008636  · 技术社区  · 3 年前

    我有一个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

    我可以做什么修改,这样我仍然可以 AttributeName() 从内部作为静态或非静态变量 MyClass ?

    0 回复  |  直到 3 年前
        1
  •  0
  •   The Dreams Wind    3 年前

    老实说,我不知道如何在派生类中使静态和非静态成员函数具有相同的名称,并在基类中区分它们。此外,我不知道是否有一种方法可以调用在派生类中声明而不在基类中声明的非静态成员函数。

    如果我们省略了这两个要求,那么您可以检查静态函数是否存在并调用它,或者回退到非静态(虚拟)函数,否则(在我的示例中,我替换了您的 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"
    }