0

ねえ、私は基本クラスのポインターを取り、それがジョイントの子孫であることを'Joint'抽出し、ポインターが実際に指している「ジョイント」の種類に基づいて正しいタイプの「定義」をインスタンス化するシリアライゼーション関数を作成しています.'type'

  • ただし、正しい型へのポインターを static_cast しても、下位クラスが持つ関数を含まない基本クラスのジョイントに関するエラーが引き続き発生します。ポインターが関数を持つ新しい型にキャストされていることをコンパイラーに認識させるにはどうすればよいですか?

  • また、「typedef」に関するエラーが発生します。これは、join* の「type」に基づいて異なる可能性があり、コンパイルは未定義であると言っています。if ステートメントの 1 つが 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;
}
4

1 に答える 1

5

あなたの使い方が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

typedefs はスコープ内で a を使用してシンボルを作成するため、typedef定義された型はスコープの終わりまで使用可能になり、それ以上は使用できなくなります。例えば:

if (foo)
{
    typedef int myInt;
    myInt var = 4; // works
}
myInt baz = 4; // fails
于 2011-08-06T05:29:09.467 に答える