我想知道是否有可能在C++中傳遞一個類作爲參數。 不傳遞一個Class對象,而是允許我像這樣使用這個類的類本身。C++傳遞一個類作爲參數
void MyFunction(ClassParam mClass)
{
mClass *tmp = new mClass();
}
以上不是真實代碼,但它有希望解釋我在示例中要做的事情。
我想知道是否有可能在C++中傳遞一個類作爲參數。 不傳遞一個Class對象,而是允許我像這樣使用這個類的類本身。C++傳遞一個類作爲參數
void MyFunction(ClassParam mClass)
{
mClass *tmp = new mClass();
}
以上不是真實代碼,但它有希望解釋我在示例中要做的事情。
您可以使用模板來完成類似的(但不完全是)的東西:
template<class T>
void MyFunction()
{
T *tmp = new T();
}
與MyFunction<MyClassName>()
調用它。
請注意,通過這種方式,您不能使用「變量」代替T
。它應該在編譯時知道。
您正在尋找templates
C++不像其他語言那樣存儲有關類的元數據。假設你一直使用一類具有無參數的構造函數,你可以使用模板來實現同樣的事情:
template <typename T>
void MyFunction()
{
T* p = new T;
}
您可以創建在您的類(ES)靜態工廠方法,它只是返回的一個新實例類,然後你可以傳遞指向該函數的指針,類似於你想要在你的例子中做的。返回類型是協變的,所以如果你所有的類都實現了相同的接口,你可以讓函數指針返回該接口。如果他們沒有一個共同的界面,你可能會留下返回void *
。無論哪種方式,如果您需要使用特定的子類,則必須使用dynamic_cast
。
你也可以傳入一個函數指針,當被調用時創建一個你想要的實例並返回它。
void MyFunction(ClassCreatorPtr makeClassFn)
{
void * myObject = makeClassFn();
}
你需要讓它返回一個指向基類的指針來做任何有趣的事情。
模板的替代方法是使用C++ 11的lambda封閉。這是我的偏好。
// in header file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator);
// in source file
IClass * MyFunctionThatDoesStuff(const IParams & interface_params,
std::function<IClass * (const IParams & interface_params)> cls_allocator) {
// Some processing. Perhaps the interface_params are generated
// inside this function instead of being passed to it.
IClass * mCls = cls_allocator(interface_params);
// Do whatever with mCls
return mCls;
}
// Somewhere else in the code.
{
Param1Type param1 = whatever1;
Param2Type param1 = whatever2;
// param1, param2, etc. are parameters that only
// SomeClsDerivedFromIClass constructor knows about. The syntax ¶m1
// achieves the closure.
// interface_param1 is common to all classes derived from IClass.
// Could more than one parameter. These parameters are parameters that
// vary from different calls of MyFunctionThatDoesStuff in different
// places.
auto cls_allocator =
[¶m1, ¶m2](const IParams & interface_params)->IClass * {
return new SomeCls1DerivedFromIClass(interface_params,
param1, param2);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
// Somewhere else in the code again.
{
ParamXType paramX = whateverX;
ParamYType paramY = whateverY;
auto cls_allocator =
[¶mX, ¶mY](const IParams & interface_params)->IClass * {
return new SomeCls2DerivedFromIClass(interface_params,
paramX, paramY);
};
IClass * mCls = MyFunctionThatDoesStuff(interface_params,
cls_allocator);
}
上面的代碼思想對於快速生成器模式或某些工廠模式變化很有效。 lambda基本上是一種工廠方法。爲了使它更加動態,您可以使用自動進行參數輸入。像這樣的東西。
auto * MyFunctionThatDoesStuff(const auto & interface_params,
std::function<auto * (const auto & interface_params)> cls_allocator);
我來自Python的影響力,你可以將類類型傳遞給函數。
2009-09-24 22:14:07
並非所有的語言都存儲有關該程序的元數據。這是現代語言的一個相對較新的特徵。 –@Martin,這是一個有趣的「相對較新」的定義,考慮到當時相當主流的Smalltalk,並且有相當多的代碼寫在裏面,70年代就是這樣做的:) – 2009-09-24 22:19:36
與許多歸因於Smalltalk的東西,Lisp在20世紀50年代就在那裏 - 整個程序是一個可以檢查和操縱的數據結構。 – 2009-09-25 08:50:34