[英]Pass generic type in c++ method as parameter
我正在嘗試實現一個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和var3。 我也不想丟失數據,例如簽名數據可能具有-ve值。
請幫助我克服這種情況,我沒有使用c ++的經驗。 我不確定我是否可以使用c ++中的templete <>來實現這一點,如果是,那么如何?
謝謝
通過指針傳遞參數:
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;
}
更優雅,更安全。
一種方法是通過函數重載:
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的類型。
最好的方法是為要更新的類型重載函數。 這將決定編譯時間,因此您可以為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);
};
演示還包括錯誤場景。
我不確定它是否與您的問題有關,因為您需要基本類型。 但我注意到沒有人提到以下內容:
一,繼承機制:
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.