C ++返回不同的对象

时间:2018-06-22 13:21:20

标签: c++ database oop auto

我有一个大问题。.我不会通过包装器类选择存储服务。返回值必须是存储服务类中的一个对象。我粘贴了当前的方法。但是到目前为止,我的想法没有奏效。

错误:

  

错误:自动返回类型的抵扣不一致:先是“ SQL *”,然后是“ REDIS *”,然后返回新的REDIS();

最重要的是拥有一个定义结构的接口类和一些“驱动程序类”,其中包含目标存储服务的所有必要操作。

希望您有另一种方法来解决此问题。

    #include <iostream>


class StorageTemplate {
    public:
        virtual bool UserhasSurName() = 0;
        virtual bool UserhasGivenName() = 0;
};

class SQL: public StorageTemplate {
    public:
        bool UserhasSurName() {
            //A SQL QUERY
            return true;
        }
        bool UserhasGivenName() {
            //AN ANOTHER SQL QUERY
            return true;
        }
};

class REDIS: public StorageTemplate {
    public:
        bool UserhasSurName() {
            //A REDIS CALL
            return false;
        }
        bool UserhasGivenName() {
            //A REDIS CALL
            return false;
        }
};


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



int main(int argc, char const *argv[])
{
    controller cont;
    auto schnitzel = cont.test(1);
    auto mitzel = cont.test(2);
    std::cout << schnitzel->UserhasSurName() << std::endl;
    std::cout << mitzel->UserhasSurName() << std::endl;
}

3 个答案:

答案 0 :(得分:1)

您面临的问题如下:考虑您的功能

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

如果您尝试评估test(1),则会扩展为

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

这会导致类型错误!

我为您展示了三种解决方法:

1。功能模板和if constexpr

使test为功能模板,并使用C ++ 17功能if constexpr检查正确的类型:

template<typename T>
auto test() {
    if constexpr(std::is_same<T, SQL>::value) {
        return new SQL();
    } else {
        return new REDIS();
    }
}

像这样在main()中使用它:

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。函数模板和std :: unique_ptr

如果要避免使用if constexpr,则可以简单地返回std::unique_ptr的实例而不是原始指针。这是首选的方法:

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

或者,您可以只返回std::make_unique<T>()

3。返回基类的实例

这是避免类型错误的最明显解决方案:仅返回基类的实例。如上所述,这里首选使用智能指针的解决方案:

std::unique_ptr<StorageTemplate> test(const int select) {
    if (select == 1) {
        return std::make_unique<SQL>();
    } else {
        return std::make_unique<REDIS>();
    }
}

如果您真的想避免使用智能指针,请使用原始指针,如下所示:

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

答案 1 :(得分:0)

在此代码中

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

auto无法推论,因为它仅与确切类型匹配。因此,即使SQLREDISStorageTemplate继承,也不会推论StorageTemplate。您需要指定类型

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

答案 2 :(得分:0)

test()中的错误返回Auto,它返回两种不同的类型。通过StorageTemplate*

进行更改
class controller {
    public:
        StorageTemplate* test(int select) {
            if( select == 1)
            {
                return new SQL(); 
            } else {
                return new REDIS();
            }
        }
};