C++ return different objects

前端 未结 3 1170
别跟我提以往
别跟我提以往 2021-01-29 12:30

i have a big problem.. I wonna select the Storage Service via a wrapper class. The returning value must be an object within the storage service class. I pasted my current approa

3条回答
  •  萌比男神i
    2021-01-29 13:07

    The problem you are facing is the following: Consider your function

    auto test(int select) {
        if (select == 1) {
            return new SQL(); 
        } else {
            return new REDIS();
        }
    }
    

    If you trying to evaluate test(1) this expands to

    auto test(int select) {
        if (true) {
            return new SQL(); 
        } else {
            return new REDIS();
        }
    }
    

    which results in a type error!

    I show you three workarounds for your problem:

    1. Function template and if constexpr

    Make test a function template and check for the correct type using the C++17 feature if constexpr:

    template
    auto test() {
        if constexpr(std::is_same::value) {
            return new SQL();
        } else {
            return new REDIS();
        }
    }
    

    Use it in main() like this:

    int main(){
        controller cont;
        auto schnitzel = cont.test();
        auto mitzel = cont.test();
        std::cout << schnitzel->UserhasSurName() << std::endl;
        std::cout << mitzel->UserhasSurName() << std::endl;
    }
    

    2. Function template and std::unique_ptr

    If you want to avoid using the if constexpr you can simply return an instance of std::unique_ptr instead of a raw pointer. This is the preferred way to do:

    template
    auto test() {
        return std::unique_ptr(new T);
    }
    

    Alternatively you can just return std::make_unique().

    3. Returning an instance of the base class

    This is is most obvious solution to avoid the type error: Just return an instance of the base class. As above a solution using smart pointers is preferred here:

    std::unique_ptr test(const int select) {
        if (select == 1) {
            return std::make_unique();
        } else {
            return std::make_unique();
        }
    }
    

    If you really want to avoid using smart pointers just use raw ones like this:

    StorageTemplate* test(const int select) {
        if (select == 1) {
            return new SQL();
        } else {
            return new REDIS();
        }
    }
    

提交回复
热议问题