问题描述
我有一个大问题..我不会通过包装器类选择存储服务.返回值必须是存储服务类中的一个对象.我粘贴了当前的方法.但是到目前为止,我的想法没有奏效.
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 approach. But my mindset didn't worked so far.
错误:
最重要的是拥有一个定义结构的接口类和一些驱动程序类",其中包含目标存储服务的所有必要操作.
The big wish is to have an interface class which defines the struct and some "driver classes" which contains all necessary operations for the target storage service.
我希望您有另一种方法可以解决这个问题.
I hope you have another approach, how I can solve this problem..
#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;
}
推荐答案
您面临的问题如下:考虑功能
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();
}
}
如果您尝试评估test(1)
,则会扩展为
If you trying to evaluate test(1)
this expands to
auto test(int select) {
if (true) {
return new SQL();
} else {
return new REDIS();
}
}
这会导致类型错误!
我为您展示了三种解决方法:
I show you three workarounds for your problem:
1.功能模板和if constexpr
1. Function template and if constexpr
使test
为功能模板,并使用C ++ 17功能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();
}
}
像这样在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
的实例,而不是原始指针.这是首选的方法:
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);
}
或者,您可以只返回std::make_unique<T>()
.
Alternatively you can just return std::make_unique<T>()
.
3.返回基类的实例
这是避免类型错误的最明显的解决方案:仅返回基类的实例.如上所述,这里首选使用智能指针的解决方案:
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();
}
}
这篇关于C ++返回不同的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!