根据具体情况在if语句中声明不同的数据类型:如何关闭编译器

Declaring different data types inside if statements depending on circumstance: how to shut up the compiler?

本文关键字:数据类型 编译器 何关闭 if 语句 声明 根据具体情况      更新时间:2023-10-16

嘿,我正在制作一个序列化函数,它接受基类指针'Joint',提取联合后代的'type',然后要实例化正确类型的'定义'基于指针真正指向的任何类型的'关节'。

  • 然而,我仍然得到关于基类关节的错误包含子代类确实具有的函数,即使我将指针静态转换为正确的类型。我怎么做编译器意识到指针被强制转换为一个新的类型有函数吗?

  • 我也得到了关于'typedef'的错误,这可能是不同的根据关节的"类型",编译器会说它是未定义的。我如何告诉编译器,无论如何,其中一个if语句将为真?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;
}

您使用static_cast是问题所在。static_cast不重新定义变量的类型:相反,它返回转换成您所要求的类型的值。

Type* variable = static_cast<Type*>(variableToCast);

同样,如果你的类使用多态性,考虑使用dynamic_cast,它利用(不是很强大的)c++的运行时类型信息系统。

if (b2DistanceJointDef* def = dynamic_cast<b2JointTypeDef*>(Joint))
{
    // if you reach this block, this means Joint is actually a pointer to
    // a b2JointTypeDef object; and you may use the `def` variable to access
    // its members
}

更好的是,如果您对这种事情感兴趣,并且在您的设计中有意义,您可以考虑使用多态方法来消除这种类型切换。关于为什么避免显式类型切换在本网站和几乎所有地方都更好,有广泛的讨论。


对于typedef语句,必须区分编译时信息和运行时信息。c++是一种静态类型语言:这意味着它需要在编译阶段了解关于变量类型的所有信息。类型定义不能根据运行时条件而变化:它需要在编译阶段进行解析。

此外,符号(基本上,任何有标识符的东西都是符号)不能在其作用域之外使用。因此,如果你在if块下声明任何东西,你将无法从if块外访问它。

由于typedef在作用域中使用typedef生成符号,因此直到作用域结束为止,定义的类型都是可用的。例如:

if (foo)
{
    typedef int myInt;
    myInt var = 4; // works
}
myInt baz = 4; // fails