将c++方法中的泛型类型作为参数传递
Pass generic type in c++ method as parameter
我正在尝试实现一个c++方法,并希望在其中传递一个泛型参数。我只想将该参数分配给对象的属性。这里有一个例子:
class Myclass {
public:
unsigned long long var1;
unsigned short var2;
signed short var3;
}
现在我在SometherClass中有一个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&var3.我也不想丢失数据,例如签名数据可能有-ve值。
请帮助我克服这种情况,我没有在c++中工作的经验。我不确定是否可以使用templete<>实现这一点在c++中,如果是,怎么办?
感谢
通过指针传递参数:
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;
}
更优雅,打字更安全。
最好的方法是为需要更新的类型重载函数。这将由编译时间决定,因此您可以为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);
};
演示,其中还包括错误场景。
一种方法是通过函数重载:
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。
我不确定它是否与您的问题有关,因为您需要基本类型。但我注意到没有人提到以下内容:
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。回调机制:
同样,我认为这对于您的问题来说可能太复杂了,但您也可以传递一个回调函数来设置特定的成员值和值。
我认为您可以使用模板来完成。例如:
#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
正如其他答案所建议的那样,有多种方法可以实现您想要的功能:模板方法、指针、重载方法、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应该根据相同的原则进行命名和类型化。
例如
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);
- 使用泛型类型推送到堆栈时出现问题
- 以特征类型作为参数的泛型函数回调
- 如何在容器中指定模板化别名的泛型类型
- 具有模板专用化的泛型类型转换
- 具有静态大小数组作为参数的泛型 lambda
- C++存储泛型 T 类型类的向量
- 如何在C++中返回没有模板的泛型类型?
- 如何在带有约束 (C++) 的函数中使用泛型类型
- 模板函数重载(泛型类型与模板模板类型)选择正确的重载
- 泛型类型别名,它们彼此不兼容
- 泛型类型转换
- 重载泛型类型的模板类时检查运算符=时的自赋值
- 在C++中,如何根据类中的参数返回不同的泛型类型
- C++错误 C2227:'->looseHealth'左侧必须指向类/结构/联合/泛型类型
- 使用泛型类型显式实例化函数模板
- 如何在参数为泛型类型的模板类中为方法类型化定义函数签名
- 用于传递正则和r值ref参数的泛型宏代码
- 在java中传递泛型类类型
- 将c++方法中的泛型类型作为参数传递
- 具有不同类型参数的泛型类型的特性类实现