C++ return different objects

前端 未结 3 1140
别跟我提以往
别跟我提以往 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条回答
  • 2021-01-29 12:56

    in this code

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

    auto can't be deduced because it only match to exact type. so even if SQL and REDIS inherite from StorageTemplate, StorageTemplate won't be deduced. you need to spécifie the type

    StorageTemplate* test(int select) {
        if( select == 1)
        {
            return new SQL(); 
        } else {
            return new REDIS();
        }
    
    0 讨论(0)
  • 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<typename T>
    auto test() {
        if constexpr(std::is_same<T, SQL>::value) {
            return new SQL();
        } else {
            return new REDIS();
        }
    }
    

    Use it in main() like this:

    int main(){
        controller cont;
        auto schnitzel = cont.test<SQL>();
        auto mitzel = cont.test<REDIS>();
        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<typename T>
    auto test() {
        return std::unique_ptr<T>(new T);
    }
    

    Alternatively you can just return std::make_unique<T>().

    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<StorageTemplate> test(const int select) {
        if (select == 1) {
            return std::make_unique<SQL>();
        } else {
            return std::make_unique<REDIS>();
        }
    }
    

    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();
        }
    }
    
    0 讨论(0)
  • 2021-01-29 13:16

    Error return Auto in test(),it's return two different types. Change by StorageTemplate*

    class controller {
        public:
            StorageTemplate* test(int select) {
                if( select == 1)
                {
                    return new SQL(); 
                } else {
                    return new REDIS();
                }
            }
    };
    
    0 讨论(0)
提交回复
热议问题