2011-07-08 19 views
1

EDIT:は、私は基本的に私は実行可能な例を提供することができ、全体の問題を刷新...私は把握することはできませんセグメンテーションフォールトを取得してきた混乱セグメンテーションフォールト

。ここで私のコードのコンパクト版です。クラスの中には関連するメソッドがないものもありますが、それは私の問題と関係があり、特に私が得ているコメントの後にあると思います。

#import <vector> 
using namespace std; 

template<class Data = float> 
    class Vector 
    { 
    // All pure virtual functions. 
    }; 

template<class Data> 
    class TranslationVector : public virtual Vector<Data> 
    { 
    // All pure virtual functions. 
    }; 

template<class Data> 
    class SimpleVector4 : public virtual Vector<Data> 
    { 
    public: 
     SimpleVector4(const Data d0, const Data d1, const Data d2, const Data d3) 
     { 
     fData = new vector<Data> ; 

     fData->push_back(d0); 
     fData->push_back(d1); 
     fData->push_back(d2); 
     fData->push_back(d3); 
     } 

     vector<Data>* 
     getData() 
     { 
     return (fData); 
     } 

    private: 
     vector<Data>* fData; 
    }; 

template<class Data> 
    class SimpleTranslationVector4 : public SimpleVector4<Data> , public TranslationVector<Data> 
    { 
    public: 
     SimpleTranslationVector4(const Data x, const Data y, const Data z, const Data w) : 
     SimpleVector4<Data> (x, y, z, w) 
     { 
     } 
    }; 

template<class Data = float> 
    class Matrix 
    { 
    // All pure virtual functions. 
    }; 

template<class Data> 
    class TransformationMatrix : public virtual Matrix<Data> 
    { 
    // All pure virtual functions. 

    virtual void 
    translate(TranslationVector<Data>* const translation) = 0; 
    }; 

template<class Data> 
    class SimpleMatrix44 : public virtual Matrix<Data> 
    { 
    public: 
     SimpleMatrix44() 
     { 
     fData = new vector<Data> (CELLS_IN_MATRIX, 0); 

     setIdentity(); 
     } 

     vector<Data>* 
     getData() 
     { 
     return (fData); 
     } 

     void 
     setIdentity() 
     { 
     fData->at(0) = 1; 
     fData->at(1) = 0; 
     fData->at(2) = 0; 
     fData->at(3) = 0; 

     fData->at(4) = 0; 
     fData->at(5) = 1; 
     fData->at(6) = 0; 
     fData->at(7) = 0; 

     fData->at(8) = 0; 
     fData->at(9) = 0; 
     fData->at(10) = 1; 
     fData->at(11) = 0; 

     fData->at(12) = 0; 
     fData->at(13) = 0; 
     fData->at(14) = 0; 
     fData->at(15) = 1; 
     } 

    private: 
     static const int CELLS_IN_MATRIX = 16; 

     vector<Data>* fData; 
    }; 

template<class Data> 
    class SimpleTransformationMatrix44 : public SimpleMatrix44<Data> , public TransformationMatrix<Data> 
    { 
    public: 
     SimpleTransformationMatrix44() : 
     SimpleMatrix44<Data>() 
     { 
     } 

     void 
     translate(TranslationVector<Data>* translation) 
     { 
     vector<Data> *data = SimpleMatrix44<Data>::getData(); 
     vector<Data> *transData = ((SimpleVector4<Data>*) translation)->getData(); 

     // The error occurs on this line: 
     data->at(12) += data->at(0) * transData->at(0) + data->at(4) * transData->at(1) + data->at(8) * transData->at(2); 
     data->at(13) += data->at(1) * transData->at(0) + data->at(5) * transData->at(1) + data->at(9) * transData->at(2); 
     data->at(14) += data->at(2) * transData->at(0) + data->at(6) * transData->at(1) + data->at(10) * transData->at(2); 
     data->at(15) += data->at(3) * transData->at(0) + data->at(7) * transData->at(1) + data->at(11) * transData->at(2); 
     } 
    }; 

int 
main(int argc, char** argv) 
{ 
    SimpleTransformationMatrix44<float> matrix1; 
    matrix1.translate(new SimpleTranslationVector4<float> (0.0f, 10.0f, 0.0f, 1.0f)); 

    return 0; 
} 

エラーが発生したコードにコメントがあります。デバッグから私は実際にvectorsize()関数で発生し、transDataは初期化されていないことがわかります。 transDataさんはまだ初期化されていません。何か案は?ありがとう、

Gaz。

+0

「transData」の取得方法の詳細を教えてください。例えば。 SimpleVector4 :: getData() 'がどのように定義されているかを示します。 'TranslationVector 'は 'SimpleVector4 'に関連しています。なぜあなたはconstを投げ捨てるのですか? 'SimpleTranslationVector4 'がどのように定義されています。等 –

+0

'(SimpleVector4 *)翻訳'なぜこの型キャスティング? – iammilind

+2

これは興味深い質問のように聞こえますが、試してみたいと思いますが、私は簡単にコンパイルして実行できるものを提供していないので、私の注意が他の場所に行きます。さようなら。 http://sscce.org –

答えて

1

無関係のタイプ間でCスタイルのキャストを実行しています。これは安全ではありません。あなたがすべてでこれを実行する必要があるという事実は、おそらくあなたの設計に問題があることを示しているが、これを交換してください:非継承クラスの

vector<Data>* transData = dynamic_cast<SimpleVector4<Data>*>(translation)->getData();

+0

それは動作します!私はひどく設計されたコードを望んでいません...今私は私の質問に適切な例があるので、あなたは見て、あなたがそれがこの状況につながった悪いデザインだと思っているのを見て気になりますか?おそらく貧弱な階層ですか?私はJavaのバックグラウンドを持ち、C++に移行しているので、私のコードスタイルはJavaをあまりにも真似しようとしているかもしれません。ありがとう。 –

3

出演:これで

vector<Data>* transData = ((SimpleVector4<Data>*) translation)->SimpleVector4<Data>::getData();

あなたのエラーと思われます。

あなたのコードを見てみましょう。 translate関数を呼び出すと、SimpleTranslationVector4<float>*からTranslationVector<float>*への変換があります。その後、変換された値は再びSimpleVector4<float>*に変換されます。しかし、SimpleVector4<float>TranslationVector<float>を継承しません。

このコードもエラーになります。

template<class Data> 
class SimpleVector4 { 
public: 
    int a; 
}; 

template<class Data> 
class TranslationVector { 
}; 

template<class Data> 
class SimpleTranslationVector4 : public SimpleVector4<Data>, 
public TranslationVector<Data> { 
}; 

int main() { 
    SimpleTranslationVector4<float> A; 
    SimpleVector4<float>* b = (SimpleVector4<float>*)&A; 
    TranslationVector<float>* c = (TranslationVector<float>*)&A; 
    SimpleVector4<float>* d = (SimpleVector4<float>*)c; 
    b->a = 1; // ok 
    d->a = 1; // error 
} 
+0

これは素晴らしい例です。あなたの答えと@bshieldsの答えの間に、私はどこが間違っていたかを理解していると思う。彼の答えにコメントしたように、私はJavaから来て、Javaのすべてのキャストは動的でなければならないと思います。 @Gary Buyn。 –

+0

私はより明確に説明しようとします。 'translation'が' SimpleVector4 * 'にキャストされた後、不正なメモリ位置を指します。したがって、 'translation-> getData()'は不正なポインタを返し、不確定な動作につながります。 C++コンパイラは 'TranslationVector *'を 'SimpleVector4 *'に変換する方法を知りません。あなたは '(SimpleVector4 *)(SimpleTranslationVector4 *)translation'を二重キャスティングすることで助けてもらえますが、それはうまくいくでしょう。詳細は[this](http://en.wikipedia.org/wiki/Virtual_method_table)を参照してください。 P.S.このメッセージを2度受け取った場合はごめんなさい。 –