我正在尝试实现一个c ++方法,并希望在其中传递一个泛型参数。我只想将该参数分配给对象的属性。这是一个例子:
class Myclass {
public:
unsigned long long var1;
unsigned short var2;
signed short var3;
}
现在我在SomeOtherClass中有一个Myclass的全局对象,方法说:
void SomeOtherClass::updateMyClassValue(int paramType, <Generic> value) {
switch(paramType) {
case1:
objMyClass.var1 = value;
case2:
objMyClass.var2 = value;
case3:
objMyClass.var3 = value;
}
}
如何传递这种类型,因为如果我使用固定类型,例如unsigned long long
作为参数类型,我将无法将其分配给var2&amp; VAR3。我也不想丢失数据,例如签名数据可能有-ve值。
请帮助我克服这种情况,我没有使用c ++的经验。我不确定我是否可以使用模板实现这一点&lt;&gt;在c ++中,如果是,那么如何?
由于
答案 0 :(得分:2)
通过指针传递参数:
void SomeOtherClass::updateMyClassValue(int paramType, void* pValue) {
switch(paramType) {
case1:
objMyClass.var1 = *(unsigned long long*)pValue;
case2:
objMyClass.var2 = *(unsigned short)pValue;
case3:
objMyClass.var3 = *(signed short)pValue;
}
这当然不是类型安全的,当你不小心指定了错误的paramType时,你会遇到很多麻烦。如果您使用成员模板函数,则可以让编译器为您进行一些检查,例如:
template<type T>
void SomeOtherClass::updateMyClassValue<short int>(T value) {
objMyClass.var2 = value;
}
更优雅,更安全。
答案 1 :(得分:1)
这样做的一种方法是通过函数重载:
template <class T>
void updateMyClassValue(T value) {
//assert, or log message, or nothing, if not needed you can remove this function
}
void updateMyClassValue(unsigned long long value) {
var1 = value;
}
void updateMyClassValue(unsigned short value) {
var2 = value;
}
void updateMyClassValue(signed short value) {
var3 = value;
}
另一种方法是使用类似boost::any的类型。
答案 2 :(得分:1)
最好的方法是为要更新的类型重载函数。这将决定编译时间,因此您可以节省switch/case
的几个周期和代码行。对于不需要的类型,您可能拥有private
功能。
以下是避免重复代码的一种方式:
#define UPDATE(VAR) VAR; \
public: void updateMyClassValue (const decltype(VAR)& value) { VAR = value; }
class Myclass {
public:
unsigned long long UPDATE(var1);
unsigned short UPDATE(var2);
signed short UPDATE(var3);
private: template<typename T> void updateMyClassValue (T);
};
Demo,其中还包含错误情景。
答案 3 :(得分:1)
我不确定是否与您的问题有关,因为您需要基本类型。但我注意到没有人提到以下内容:
I。继承机制:
class BaseType;
class Var1 : public BaseType
{};
class Var2 : public BaseType
{};
class Var3 : public BaseType
{};
class Myclass
{
public:
Var1 m_var1;
Var2 m_var2;
Var3 m_var3;
};
void SomeOtherClass::updateMyClassValue(int paramType, BaseType value) {
switch(paramType) {
case1:
objMyClass.m_var1 = value;
case2:
objMyClass.m_var2 = value;
case3:
objMyClass.m_var3 = value;
}
}
当然,没有类型检查等, 但这是有效的选项,需要在 编译时间 上进行检查。
II。回调机制:
同样,对于您的问题,我认为这可能太麻烦了,但是您也可以传递用于设置特定成员值和值的回调函数。
答案 4 :(得分:0)
我认为你可以使用模板来做到这一点。例如:
#include <iostream>
using namespace std;
class Myclass {
public:
unsigned long long var1;
unsigned short var2;
signed short var3;
};
class SomeOtherClass
{
public:
Myclass objMyClass;
template <typename T>
void updateMyClassValue(int paramType, T value);
};
template <typename T>
void SomeOtherClass::updateMyClassValue(int paramType, T value) {
switch(paramType) {
case 1:
objMyClass.var1 = value;
case 2:
objMyClass.var2 = value;
case 3:
objMyClass.var3 = value;
}
}
int main() {
SomeOtherClass soc;
unsigned long long var1 = 11;
unsigned short var2 = 22;
signed short var3 = 33;
soc.updateMyClassValue(1, var1);
soc.updateMyClassValue(2, var2);
soc.updateMyClassValue(3, var3);
cout << soc.objMyClass.var1 << endl;
cout << soc.objMyClass.var2 << endl;
cout << soc.objMyClass.var3 << endl;
return 0;
}
输出结果为:
11
22
33
答案 5 :(得分:0)
有多种方法可以做你想要的,其他答案建议:模板方法,指针,重载方法,像boost::any
这样的泛型类型。
但在选择其中之一之前,请从设计角度审视您的问题。您有一个具有三个不同类型的成员变量的类。他们意味着什么,他们代表什么?它们是类的完全相同属性的不同表示,还是它们与该类完全不同的属性(从OO角度考虑类,而不是简单的C ++语法结构)?
案例1 - 表示相同值的不同方式
在这种情况下,考虑将值存储在类中的单个表单中,并根据需要将其转换为其他表示形式。
例如:您正在设计一个可以保持摄氏或华氏温度的Temperature
类。无需成员以两种格式存储温度,只需一个,并在需要时将其转换为其他格式。
class Temperature
{
public:
void setCelsius(double degrees)
{
celsiusTemperature = degrees;
}
void setFahrenheit(double degrees)
{
celsiusTemperature = (degrees - 32) * 5.0 / 9.0;
}
double getCelsius() const
{
return celsiusTemperature;
}
double getFahrenheit() const
{
return celsiusTemperature * 9.0 / 5.0 + 32;
}
private:
double celsiusTemperature;
}
案例2 - 类的不同值/属性
如果变量包含类的不同属性并且表示不同的东西,则使用不同的方法来设置它们,而不是设置它们中的每一个的通用方法。变量应根据其目的和它存储的值的含义进行命名和输入。应根据相同的原则命名和输入变量的setter。
E.g。
class Person
{
public:
private:
string name;
int age;
double height;
}
在这种情况下,拥有通用方法
会更加明显void setPersonAttribute(int attributeType, T value);
或为每个属性设置方法
void setName(string name);
void setAge(int age);
void setHeight(double height);