c++将不同的类传递到函数中
c++ pass different classes into function
我可能完全错了方向,但已经晚了,这让我有点生气。
我的基类中有一个函数,它应该允许我创建派生类的新对象。然而,在它说Melee的地方,我希望它可以与我的其他派生类互换。我不知道如何传入不同的类,所以它会创建该类的对象。
void BaseUnit::CreateNewUnit(vector<BaseUnit*>& MyVector)
{
UnitID++;
MyVector.push_back(new Melee());
}
您可以使用"原型设计模式"。
在std::map
中放入associations键->prototype,就完成了:当用户按下某个键时,您可以查找映射,提取原型并将其传递给CreateNewUnit
。在CreateNewUnit中,您将使用Prototype::Clone()
class BaseUnit
{
public:
... // your methods
virtual BaseUnit* Clone() = 0;
};
class Melee : public BaseUnit
{
public:
BaseUnit* Clone() { return new Melee(); }
};
void BaseUnit::CreateNewUnit(vector<BaseUnit*>& MyVector, BaseUnit* prototype )
{
UnitID++;
MyVector.push_back( prototype -> Clone() );
}
int main()
{
std::map< char, BaseUnit* > prototypes;
prototypes[ 'a' ] = new Melee();
prototypes[ 'b' ] = new OtherUnit();
...
std::vector< BaseUnit* > units;
char selection = GetKeyPressed();
BaseUnit::CreateNewUnit( units, prototypes[ selection ] );
}
此解决方案的好处是,当您需要在应用程序中添加新的单元类型时,您只需在原型映射中添加一个新条目。
顺便说一句:如果从BaseUnit派生的类在全局"原型"映射中注册,只需付出一点努力,您甚至可以避免这种情况。
我要么将指针传递给单元:
void BaseUnit::CreateNewUnit(vector<BaseUnit*>& MyVector, BaseUnit* unit)
{
UnitID++;
MyVector.push_back(unit);
}
或者通过按下的键或其他id:
void BaseUnit::CreateNewUnit(vector<BaseUnit*>& MyVector, char type)
{
switch(type) //this would be the key pressed
{
case '1':
MyVector.push_back(new Melee());
UnitID++;
break;//this would be continued for all possible units
}
}
如果您希望在编译时确定它,您可以使用模板方法或为每个类创建一个方法。这叫做工厂方法,是一种设计模式。请注意,此处对工厂的"提示"是模板参数。
如果希望在运行时确定,则需要以某种方式标识相关类,即工厂的"提示"。大多数情况下,这将是一个枚举或字符串。再次阅读工厂设计模式和工厂方法。
这可能会让您了解如何做到这一点:1.改变函数签名以包括导出的对象指针作为第二参数
void BaseUnit::CreateNewUnit(vector<BaseUnit*>& MyVector, const BaseUnit* derived) {
UnitID++;
MyVector.push_back(derived);
}
按键时调用上述函数,如果按键被按下,则创建一个新的派生对象并调用ur函数:
Melee*m=新Melee();
unit.CreateNewUnit(myVector,m);
如果在编译时需要,您可以简单地使用工厂模板。如果不同的类有不同的参数需要传递,您应该使用一个可变模板:
#include <utility>
class Factory {
...
template <typename Derived, typename ...Args>
BaseUnit * create(Args &&... args)
{
return new Derived(std::forward<Args>(args)...);
}
};
然后,您可以简单地创建一个工厂并调用factory.create(Melee, optional_arguments)
或任何类型,然后将创建一个模板专门化,用提供的参数实例化该特定类型。
如果您需要一个"运行时调度"创建函数,您可以在BaseUnit
中有一个类似enum Type
的东西,或者有一个列出所有可能派生类型的其他id,并有一个create(BaseUnit::Type type)
方法,该方法带有switch (type)
语句,每个对象类型都有一个case,用于创建适当的类型。当然,这可以与上面列出的模板工厂结合使用。
switch语句将比映射高效得多,此外,如果映射是"静态"填充的,那么它将没有真正的意义。只有当您想在运行时注册新的对象创建方法时,映射才有意义。在这种情况下,您可以拥有一个类型id的映射和一个指向函数的指针,从而返回一个新的派生BaseType
。例如,通过这种方式,您可以注册从动态库加载的额外函数,根据类型id查找函数指针,并使用它来实例化该类型的对象。但这只是在您需要运行时注册的情况下。否则,请坚持以前的解决方案。只有当你有像"插件"这样的东西时,这才是合理的——动态库提供了一组额外的类型和创建它们的适当函数,这样你就可以加载库,在地图中注册其组件,并能够实例化在游戏"核心逻辑"实现过程中不存在的类型。当然,这一切都必须依赖于核心逻辑所围绕的多态接口才能工作,否则就不会了。此外,对于这个解决方案,您可能希望id是字符串而不是整数,因为它提供了更大的灵活性,并且没有switch语句的限制。
另外请注意,我没有包括你的vector<BaseUnit*>& MyVector
-IMO,它不应该是你传递的参数,而是你的游戏类的本地成员,你可以直接访问它,而不需要将其作为参数。
此外,请遵循适当的编码约定,不要使用成员方法、对象或参数的大写字母。这只是令人困惑。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗