C++ C++;创建一个通用接口
我有一个接口(缺少很多成员,但请注意这个接口是强制性的)。我需要从中继承5个类,它们将具有_value属性。那么,ins\ 除了实现5个类(对于char、short、int、float、double),我还考虑了一个模板类:C++ C++;创建一个通用接口,c++,interface,polymorphism,C++,Interface,Polymorphism,我有一个接口(缺少很多成员,但请注意这个接口是强制性的)。我需要从中继承5个类,它们将具有_value属性。那么,ins\ 除了实现5个类(对于char、short、int、float、double),我还考虑了一个模板类: class my_interface { public: virtual [various_types] getValue() const = 0; }; template<typename T> class my_class : public
class my_interface
{
public:
virtual [various_types] getValue() const = 0;
};
template<typename T>
class my_class : public my_interface
{
private:
T _value;
public:
my_class(T value) : _value(value) {} // initialize the attribute on construct
virtual T getValue() const { return _value; }
};
class my\u接口
{
公众:
虚拟[各种类型]getValue()常量=0;
};
模板
类my_类:公共my_接口
{
私人:
T_值;
公众:
my_类(T值):_值(值){}//初始化构造上的属性
虚拟T getValue()常量{return_value;}
};
…这样类似的东西才能起作用:
void my_function()
{
my_inteface* a = new my_class<char>(42);
my_interace* b = new my_class<short>(21);
int result;
result = a->getValue() + b->getValue();
}
void my_函数()
{
my_inteface*a=新的my_类(42);
my_interace*b=新的my_类(21);
int结果;
结果=a->getValue()+b->getValue();
}
但我不知道我能做什么。看起来你不能在纯虚拟界面上制作模板。对我来说,唯一可行的方法是使getValue()始终返回一个double,因为它是我需要的最大大小的类型。但是,我不喜欢这种解决方案。记住“virtual…”的意思是“在类中创建一个函数指针,我将使用它调用正确的派生类”。它只是一个指针,所以在调用它之前,必须就返回类型达成一致。C++没有动态的类型和其他语言的反射——它必须知道调用类型之前的返回类型。 如果您的接口上只有一个方法(GETValueAudio),那么您只需要模板类实现。 但是,如果要创建这样的接口:
std::string getValue();
int getValue();
long getValue();
enum ValType{
INT, CHAR, STR, DEQUE
};
class Wrapper{
private:
union S{
int intVal;
char charVal;
std::string stringVal;
std::deque dequeVal;
~S() {}
} theVal;
ValType heldType;
public:
void setVal(int value){ heldType = INT; theVal.intVal = value; }
void setVal(char value){ heldType = CHAR; theVal.charVal = value; }
// ... and so on
int getIntVal() const {
if(heldType!=INT)
throw std::runtime_error("Cop on");
return theVal.int;
}
// and so on
}
那么您就不走运了,因为您不能仅基于返回类型重载函数名。或者,您可以创建一个包装器类型
编辑
通过包装器类型,我的意思是,如果getValue需要返回多个类型,那么可以通过多种方式使用包装器类来完成,该包装器类封装了所需的功能,而不是将其添加到顶级接口。它可能看起来像这样:
std::string getValue();
int getValue();
long getValue();
enum ValType{
INT, CHAR, STR, DEQUE
};
class Wrapper{
private:
union S{
int intVal;
char charVal;
std::string stringVal;
std::deque dequeVal;
~S() {}
} theVal;
ValType heldType;
public:
void setVal(int value){ heldType = INT; theVal.intVal = value; }
void setVal(char value){ heldType = CHAR; theVal.charVal = value; }
// ... and so on
int getIntVal() const {
if(heldType!=INT)
throw std::runtime_error("Cop on");
return theVal.int;
}
// and so on
}
那么你的界面就是
public class my_interface{
virtual Wrapper getVal();
}
您在这里并没有获得太多,因为用户仍然需要调用包装器的正确子成员。
如果需要,也可以将返回值表示为字符串
请注意,使用活接头时,您需要注意以下注意事项:
编辑2:
你可以用模板返回来实现这一点
template<typename = T>
const T& getVal(const T& typeToAllowMethodOverriding) const;
模板
常数T&getVal(常数T&typeToAllowMethodOverriding)常数;
您也可以将类my_接口设置为模板类:
template<typename T>
class my_interface
{
public:
virtual T getValue() const = 0;
};
模板
类my_接口
{
公众:
虚拟T getValue()常量=0;
};
这将为您使用的每个类型T生成一个接口和一个类。template
template<typename U>
class my_interface
{
public:
virtual U getValue() const = 0;
};
template<typename T>
class my_class : public my_interface<T>
{
private:
T _value;
public:
my_class(T value) : _value(value) {} // initialize the attribute on construct
T getValue() const { return _value; }
};
类my_接口
{
公众:
虚拟U getValue()常量=0;
};
模板
类my_类:公共my_接口
{
私人:
T_值;
公众:
my_类(T值):_值(值){}//初始化构造上的属性
T getValue()常量{return_value;}
};
它适用于所有类型,但对于字符串类型,您必须对模板进行专门化我认为您最好使用/实现类似的功能
您还可以将
boost::variant
包装到另一个类中,以提供基本类型的转换运算符。可能的重复项您需要对类型进行所有算术运算还是有限?你总是会遇到这样的问题:你不知道子类的实际类型。你的问题是你根本不能将像[各种类型]
这样的返回类型作为虚拟函数的返回类型,除非您编写了