简体   繁体   中英

Handling both static and non static functions in c++

I have a c++ class, part of its defintion is:

template <class InputClass>
class MyClass

And InputClass is defined as a child class of MyClass:

class InputClass: public MyClass<InputClass>

there are many places in MyClass that has this call:

InputClass::AttributeName()

Where AttributeName() is defined on different child classes of InputClass as:

static std::string AttributeName

However, recently, there's specific child class of InputClass in which we have to define attributeName as non static, because we want different instances of this new child class to NOT share AttributeName ):

std::string AttributeName

What modifications can I make such that I can still AttributeName() either as a static or non-static variable from inside MyClass ?

To be honest I can't see how to make a static and a non-static member functions with the same name in derived classes and differentiate between them in the base class. Also, I don't know if there is a way to call a non-static member function which is declared in the derived class and is not declared in the base class.

If we omit those two requirements, then you could check whether the static function exists and call it, or fallback to a non-static (virtual) function otherwise (in my example I replaced your AttributeName function with static_name and name for static and non-static functions correspondingly):

#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";
    }
};

Now, in the base Item class you can decide on which function to use like this:

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;
        }
    };
    ...
}

And how it can be used in the client code:

int main() {
    DerivedNonStatic dns;
    dns.printName(); // prints "non-static item"

    DerivedStatic ds;
    ds.printName(); // prints "static item"
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM