2016-08-31 18 views
-2

テンプレートクラスが1つのテストで失敗するようです。式ノードのテンプレートコンストラクタが間違った値を返す

  • 表現グラフのノード値を表すテンプレート構造 "term"があります。
  • グラフを表すテンプレート構造 "式"があります。
  • 試験手順「無効テスト()」

は、私は今、数時間のために私の頭を打つしているがあります。私は本当に助けてほしい。

void Test() 
{ 
    cout << "**** Integer Tests" << endl; 
    // Default Constructor 
    integer a; 
    cout << "integer a = "<< a.Value << endl; 
    // Copy Constructor 
    integer b(a); 
    cout << "integer b(a) = "<< b.Value << endl; 
    integer c = b; 
    cout << "integer c = b = "<< c.Value << endl; 
    // Type Constructor 
    integer d(5); 
    cout << "integer d(5) = "<< d.Value << endl; 
    integer e = 5; 
    cout << "integer e = 5 = "<< e.Value << endl; 
    // Type Conversions 
    int n = e.Value; 
    cout << "n = e = "<< n << endl;/ 
    n = (int)d.Value + (int)e.Value; 
    cout << "n = d + e = "<< n << endl;// allowed because a convers to int 

    cout << "**** Expression Tests" << endl; 
    expression<int> e1; 
    expression<int> e2(e1); 

    expression<int> e3(d);// This line using the copy constructor works 
    expression<int> e4 = d + e;// this line, using the copy constructor AFTER the operator+ call results in BUM values. 

} 

試験機能 "ボイド試験()" ステートメントの正しい値を与えることができない:

発現E4 = D + E。

Tに...コール・スタックを介してステッピング+ 1

1.)用語::発現&オペレータ+(用語& REF)

2)戻り、左と右の値のコール式ノードの正解!!!それはコピーコンストラクタ式(表現&参照)

4)WTFを呼び出して、今

3)、失敗した割り当て... ???この中で私はバーン左右の値を取得します。

なぜ、コピーコンストラクタテストが上記の行で成功したのですか?ここ

上記のコードのテストケーステンプレート

template<typename T> struct expression; // Forward Declare expressions, so i can use it in operator+ 

template<typename T> 
struct term 
{ 
    T Value; 
    term() : Value(0) 
    { 
     cout << "**** term()" << endl; 
    } // Default Constructor 
    term(term& ref) : Value(ref.Value) 
    { 
     cout << "**** term(term& ref)" << endl; 
    } // Copy Constructor 
    // Type Conversion 
    term(T value) : Value(value) 
    { 
     cout << "**** term(T value)" << endl; 
    } // Type Constructor 
    //operator T() const { return Value; } // Type Converter 
    **expression<T>& operator+(term& ref) 
    { 
     return expression<T>(*this, ref); 
    };** 
}; 

template<typename T> 
struct expression 
{ 
    term<T> Left; 
    term<T> Right; 
    expression() 
     : Left() 
     , Right() 
    { 
     cout << "**** expression()" << endl; 
     cout << "left" << Left.Value << endl; 
     cout << "right" << Right.Value << endl; 
    } 
    expression(expression& ref) 
     : Left(ref.Left) 
     , Right(ref.Right) 
    { 
     cout << "**** expression(expression& ref)" << endl; 
     cout << "left" << Left.Value << endl; 
     cout << "right" << Right.Value << endl; 
    } 
    expression(term<T>& left) 
     : Left(left) 
     , Right() 
    { 
     cout << "**** expression(term<T>& left)" << endl; 
     cout << "left" << Left.Value << endl; 
     cout << "right" << Right.Value << endl; 
    } 
    expression(term<T>& left, term<T>& right) 
     : Left(left) 
     , Right(right) 
    { 
     cout << "**** expression(term<T>& left, term<T>& right)" << endl; 
     cout << "left" << Left.Value << endl; 
     cout << "right" << Right.Value << endl; 
    } 
}; 
struct integer : public term<int> 
{ 

    integer() : term() { }// allows default constructor (not inheritablle) 
    // tactic to get base class constructors(1 parameter) to compile... 
    template<class T> integer(T t) : term(t) { } 
    //template<class T> integer(T& t) : term(t) { } 
}; 
void Test() 
{ 
    cout << "**** Integer Tests" << endl; 
    // Default Constructor 
    integer a; 
    cout << "integer a = "<< a.Value << endl;// allowed because integer converts to int 
    // Copy Constructor 
    integer b(a); 
    cout << "integer b(a) = "<< b.Value << endl; 
    integer c = b; 
    cout << "integer c = b = "<< c.Value << endl; 
    // Type Constructor 
    integer d(5); 
    cout << "integer d(5) = "<< d.Value << endl; 
    integer e = 5; 
    cout << "integer e = 5 = "<< e.Value << endl; 
    // Type Conversions 
    int n = e.Value; 
    cout << "n = e = "<< n << endl;// allowed because a convers to int 
    // Arithmetic using base type operators... whatever they allow, is allowed. 
    n = (int)d.Value + (int)e.Value; 
    cout << "n = d + e = "<< n << endl;// allowed because a convers to int 

    cout << "**** Expression Tests" << endl; 
    expression<int> e1; 
    expression<int> e2(e1); 

    expression<int> e3(d);// This line using the copy constructor works 
    expression<int> e4 = d + e;// this line, using the copy constructor AFTER the operator+ call results in BUM values. 

} 

出力がどのように見えるされています

**** Integer Tests 
**** term() 
integer a = 0 
**** term(term& ref) 
integer b(a) = 0 
**** term(term& ref) 
integer c = b = 0 
**** term(T value) 
integer d(5) = 5 
**** term(T value) 
integer e = 5 = 5 
n = e = 5 
n = d + e = 10 
**** Expression Tests 
**** term() 
**** term() 
**** expression() 
left0 
right0 
**** term(term& ref) 
**** term(term& ref) 
**** expression(expression& ref) 
left0 
right0 
**** term(term& ref) 
**** term() 
**** expression(term<T>& left) 
left5 
right0 
**** term(term& ref) 
**** term(term& ref) 
**** expression(term<T>& left, term<T>& right) 
left5 
right5 
**** term(term& ref) 
**** term(term& ref) 
**** expression(expression& ref) 
left4061292 
right4061296 

編集:(私が加えるかもしれない、非常に迅速に)指摘したよう演算子+ました私が想定した値ではなく、スタック上のtempへの参照を返します。

機能は、発現後にアンパサンドが除去されるように固定した:

expression<T> operator+(term& ref) 
    { 
     return expression<T>(*this, ref); 
    }; 

これはID10Tエラーでした。アンパサンドは私の目の前にあった。

この問題を解決するお手伝いをありがとうございます。ここで

答えて

2

はあなたの問題です:

expression<T>& operator+(term& ref) 

operator+は、新しいオブジェクトを返す必要があります。一時的な参照を返しています。コンパイルする必要がありますが、MSVCを使用していると推測していますが、これは私が理解できない理由でこれを許可する拡張機能です。

コードにはコンパイルできないような問題がありますが、エラーが発生する可能性があります。最初の近似として、コード内の参照の使用はすべて間違っています - それらはすべてconstまたは値への参照である必要があります。

+0

実際、コードは実際にはコンパイルされません。コードはエラー行の上の行でも機能します。その意図は、演算子+が返り値としてスタック上の式構造体を返すことです(それはちょうど64ビットです)。典型的な演算子+自身への参照を返します...私はそれを行うことはできません。このコードはそれの上の行でも動作します。申し訳ありませんが、正しい答えではありません。 –

+0

注意:1つのoperator + callを実行し、コピーコンストラクタに正しく戻ります。ここで、値が正しいこと、および代入文の2番目のコピー...スタック上に作成されたrefコピーがどこにありますか戻ってきた。あなたは何を言っている、私はそれをコピーする前に私のコピーを上書きスタックを見ている?あなたは正しいかもしれません。 –

+0

@GunterDon典型的な 'operator + ='は自身への参照を返します。 'operator +'は値で返します。 MSVCで '/ Za'コンパイラスイッチを使用すると、これらの無効なバインディングにエラーが発生します。 –

関連する問題