根据情况在 if 语句中声明不同的数据类型:如何关闭编译器?
嘿,所以我正在制作一个序列化函数,它采用基类指针'Joint'
,提取联合后代的'type'
,然后想要基于指针实际指向的任何类型的“关节”来实例化正确类型的“定义”。
但是我仍然收到有关基类联合的错误 包含后代类确实具有的函数,即使我 static_cast 将指针指向正确的类型。 我该如何制作 编译器意识到指针也被转换为新类型 有这个功能吗?
我也收到有关“typedef”的错误,该错误可能有所不同 基于联合*的“类型”,编译说它是 不明确的。 我如何告诉编译器无论如何,其中一个 if 语句将为 true? (Jointdef 在 if 内部声明 语句)
这是来源:
template<class Archive>
b2Joint* const preSave(Archive & ar, b2Joint* Joint)
{
int Type = Joint->GetType();
ar & Type; // pulled out first so we know what kind of JointDef to instantiate
if(Type == b2JointType::e_distanceJoint){
b2DistanceJointDef JointDef;
static_cast<b2DistanceJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.length= Joint->GetLength();
JointDef.frequencyHz= Joint->GetFrequency();
}
if(Type == b2JointType::e_weldJoint){
b2WeldJointDef JointDef;
static_cast<b2WeldJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.referenceAngle= Joint->GetReferenceAngle(); // function added
}
if(Type == b2JointType::e_gearJoint){ //TODO / NOTE: this must be loaded last since to be linked joints must first be made
b2GearJointDef JointDef; // unless joints are in order of when they were created.......
static_cast<b2GearJoint *>(Joint);
JointDef.joint1= Joint->GetJoint1; //function added
JointDef.joint2= Joint->GetJoint2; //function added
JointDef.ratio= Joint->GetRatio();
}
if(Type == b2JointType::e_lineJoint){
b2LineJointDef JointDef;
static_cast<b2LineJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.enableLimit; Joint->IsLimitEnabled();
JointDef.localAxisA= Joint->GetLocalAxisA() //function made
JointDef.lowerTranslation= Joint->GetLowerLimit();
JointDef.upperTranslation= Joint->GetUpperLimit();
JointDef.enableMotor= Joint->IsMotorEnabled();
JointDef.maxMotorForce= Joint->GetMaxMotorForce();
JointDef.motorSpeed= Joint->GetMotorSpeed();
}
if(Type == b2JointType::e_mouseJoint){
b2MouseJointDef JointDef;
static_cast<b2MouseJoint *>(Joint);
JointDef.target= Joint->GetTarget();
JointDef.maxForce= Joint->GetMaxForce();
JointDef.frequencyHz= Joint->GetFrequency();
JointDef.dampingRatio= Joint->GetDampingRatio();
}
if(Type == b2JointType::e_prismaticJoint){
b2PrismaticJointDef JointDef;
static_cast<b2PrismaticJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.enableLimit; Joint->IsLimitEnabled();
JointDef.referenceAngle= Joint->GetReferenceAngle(); //added function
JointDef.localAxis1= Joint->GetLocalAxis1(); //added function
JointDef.maxMotorForce= Joint->GetMaxMotorForce(); //added function
JointDef.lowerTranslation= Joint->GetLowerLimit();
JointDef.upperTranslation= Joint->GetUpperLimit();
JointDef.enableMotor= Joint->IsMotorEnabled();
JointDef.motorSpeed= Joint->GetMotorSpeed();
}
if(Type == b2JointType::e_pulleyJoint){
b2PulleyJointDef JointDef;
static_cast<b2PulleyJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.groundAnchorA= Joint->GetGroundAnchorA();
JointDef.groundAnchorB= Joint->GetGroundAnchorB();
JointDef.lengthA= Joint->GetLength1();
JointDef.lengthB= Joint->GetLength2();
JointDef.maxLengthA= Joint->GetMaxPulleyLengthA(); //added function
JointDef.maxLengthB= Joint->GetMaxPulleyLengthB(); //added function
JointDef.ratio= Joint->GetRatio();
}
if(Type == b2JointType::e_revoluteJoint){
b2RevoluteJointDef JointDef;
static_cast<b2RevoluteJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.enableLimit; Joint->IsLimitEnabled();
JointDef.enableMotor= Joint->IsMotorEnabled();
JointDef.motorSpeed= Joint->GetMotorSpeed();
JointDef.maxMotorTorque= Joint->GetMaxMotorTorque() //added function
JointDef.referenceAngle Joint->GetReferenceAngle() //added function
JointDef.lowerAngle= Joint->GetLowerLimit();
JointDef.upperAngle= Joint->GetUpperLimit();
}
else{ b2JointDef
//if(Type == b2JointType::e_frictionJoint){ QUESTION: what is this... not in box2d guide...
// base class JointDef data:
JointDef.type= Joint->GetType();
JointDef.userData= Joint->GetUserData();
JointDef.bodyA= Joint->GetBodyA();
JointDef.bodyB= Joint->GetBodyB();
JointDef.collideConnected= Joint->IsCollideConnected(); //added function
ar & JointDef;
return Joint;
}
Hey so I'm making a serialization function that takes a base class pointer 'Joint'
, extracts the 'type'
of joint descendent it is, and then want to instantiate the correct type of 'definition' based on whatever kind of 'joint' the pointer is really pointing too.
However i'm still getting errors about the base class joint not
containing functions that a descendent class does have, even though i
static_cast the pointer to the correct type. How do i make the
complier realize the pointer is being casted too a new type that does
have the function?I also am getting errors about the 'typedef', which can be different
based on what 'type' the joint* is, with the compile saying it's
undefined. How do i tell the compiler that no matter what, one of the if statements will be true? (Jointdef is declared inside the if
statements)
Here's the source:
template<class Archive>
b2Joint* const preSave(Archive & ar, b2Joint* Joint)
{
int Type = Joint->GetType();
ar & Type; // pulled out first so we know what kind of JointDef to instantiate
if(Type == b2JointType::e_distanceJoint){
b2DistanceJointDef JointDef;
static_cast<b2DistanceJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.length= Joint->GetLength();
JointDef.frequencyHz= Joint->GetFrequency();
}
if(Type == b2JointType::e_weldJoint){
b2WeldJointDef JointDef;
static_cast<b2WeldJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.referenceAngle= Joint->GetReferenceAngle(); // function added
}
if(Type == b2JointType::e_gearJoint){ //TODO / NOTE: this must be loaded last since to be linked joints must first be made
b2GearJointDef JointDef; // unless joints are in order of when they were created.......
static_cast<b2GearJoint *>(Joint);
JointDef.joint1= Joint->GetJoint1; //function added
JointDef.joint2= Joint->GetJoint2; //function added
JointDef.ratio= Joint->GetRatio();
}
if(Type == b2JointType::e_lineJoint){
b2LineJointDef JointDef;
static_cast<b2LineJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.enableLimit; Joint->IsLimitEnabled();
JointDef.localAxisA= Joint->GetLocalAxisA() //function made
JointDef.lowerTranslation= Joint->GetLowerLimit();
JointDef.upperTranslation= Joint->GetUpperLimit();
JointDef.enableMotor= Joint->IsMotorEnabled();
JointDef.maxMotorForce= Joint->GetMaxMotorForce();
JointDef.motorSpeed= Joint->GetMotorSpeed();
}
if(Type == b2JointType::e_mouseJoint){
b2MouseJointDef JointDef;
static_cast<b2MouseJoint *>(Joint);
JointDef.target= Joint->GetTarget();
JointDef.maxForce= Joint->GetMaxForce();
JointDef.frequencyHz= Joint->GetFrequency();
JointDef.dampingRatio= Joint->GetDampingRatio();
}
if(Type == b2JointType::e_prismaticJoint){
b2PrismaticJointDef JointDef;
static_cast<b2PrismaticJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.enableLimit; Joint->IsLimitEnabled();
JointDef.referenceAngle= Joint->GetReferenceAngle(); //added function
JointDef.localAxis1= Joint->GetLocalAxis1(); //added function
JointDef.maxMotorForce= Joint->GetMaxMotorForce(); //added function
JointDef.lowerTranslation= Joint->GetLowerLimit();
JointDef.upperTranslation= Joint->GetUpperLimit();
JointDef.enableMotor= Joint->IsMotorEnabled();
JointDef.motorSpeed= Joint->GetMotorSpeed();
}
if(Type == b2JointType::e_pulleyJoint){
b2PulleyJointDef JointDef;
static_cast<b2PulleyJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.groundAnchorA= Joint->GetGroundAnchorA();
JointDef.groundAnchorB= Joint->GetGroundAnchorB();
JointDef.lengthA= Joint->GetLength1();
JointDef.lengthB= Joint->GetLength2();
JointDef.maxLengthA= Joint->GetMaxPulleyLengthA(); //added function
JointDef.maxLengthB= Joint->GetMaxPulleyLengthB(); //added function
JointDef.ratio= Joint->GetRatio();
}
if(Type == b2JointType::e_revoluteJoint){
b2RevoluteJointDef JointDef;
static_cast<b2RevoluteJoint *>(Joint);
JointDef.localAnchorA= Joint->GetAnchorA();
JointDef.localAnchorB= Joint->GetAnchorB();
JointDef.enableLimit; Joint->IsLimitEnabled();
JointDef.enableMotor= Joint->IsMotorEnabled();
JointDef.motorSpeed= Joint->GetMotorSpeed();
JointDef.maxMotorTorque= Joint->GetMaxMotorTorque() //added function
JointDef.referenceAngle Joint->GetReferenceAngle() //added function
JointDef.lowerAngle= Joint->GetLowerLimit();
JointDef.upperAngle= Joint->GetUpperLimit();
}
else{ b2JointDef
//if(Type == b2JointType::e_frictionJoint){ QUESTION: what is this... not in box2d guide...
// base class JointDef data:
JointDef.type= Joint->GetType();
JointDef.userData= Joint->GetUserData();
JointDef.bodyA= Joint->GetBodyA();
JointDef.bodyB= Joint->GetBodyB();
JointDef.collideConnected= Joint->IsCollideConnected(); //added function
ar & JointDef;
return Joint;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您对
static_cast
的使用是问题所在。static_cast
不会重新定义变量的类型:相反,它返回转换为您要求的类型的值。另外,如果您的类使用多态性,请考虑使用
dynamic_cast
,它利用了 C++ 的(不是非常强大的)运行时类型信息系统。更好的是,如果您喜欢这种事情,并且它在您的设计中有意义,您可以考虑使用多态方法来消除这种类型开关。关于为什么在这个网站和几乎所有地方都最好避免显式类型切换存在广泛的讨论。
对于
typedef
语句,您必须区分编译时信息和运行时信息。 C++ 是一种静态类型语言:这意味着它在编译阶段需要了解有关变量类型的所有信息。类型定义不能根据运行时条件而变化:它需要在编译阶段进行解析。此外,符号(基本上,任何具有标识符的东西都是符号)不能在其范围之外使用。因此,如果您在
if
块下声明任何内容,您将无法从该if
块外部访问它。由于
typedef
在作用域内使用typedef
生成符号,因此定义的类型在作用域结束之前都可用,并且不会再进一步。例如:Your use of
static_cast
is the problem.static_cast
does not redefine the type of a variable: instead, it returns the value casted into the type you've asked for.Also, if your classes make use of polymorphism, consider using
dynamic_cast
instead, which makes use of the (not very powerful) run-time type information system of C++.Better yet, if you're into that kind of thing, and if it makes sense in your design, you might consider a polymorphic method to eliminate this type switch. There is broad discussion about why it's better on this site and almost everywhere to avoid explicit type switches.
For the
typedef
statement, you have to make the distinction between compile-time information and runtime information. C++ is a statically typed language: this means it needs to know everything about the type of a variable during the compilation stage. A type definition cannot vary based on a runtime condition: it needs to be resolved during the compilation stage.Besides, symbols (basically, anything that has an identifier is a symbol) cannot be used outside their scope. So if you declare anything under an
if
block, you won't be able to access it from outside thatif
block.Since
typedef
s make symbols using atypedef
inside a scope makes the defined type available until the end of the scope, and no further. For instance: