2017-08-02 16 views
0

逆参照演算子で新しいノードを作成しようとしています。C++:ノード値にアクセスできない

私の主な機能

int main() 
{ 
    Insert(3); 
    return 0; 
} 

挿入()関数

void Insert(int data) 
{ 
    Node *temp = new Node ; 
    temp -> data = data ; 
    temp -> next = NULL ; 

    cout << *temp ; 

} 

マイエラー:

tp.cpp: In function ‘void Insert(int)’: 
tp.cpp:27:10: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘Node’) 
    cout << *temp ; 
+1

標準ライブラリに 'Node'の' <<'オーバーロードはありません。あなたはまた、 'Node * temp = new Node;'をリークします – user4581301

+0

次にノードの値を見てから、私は今宣言しましたか? ありがとう! –

+1

'Node'を扱うための独自の' << '演算子を書く必要があります。 Stream(Bitshift)演算子を参照してください。https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading – user4581301

答えて

1

問題: C++提供その基本型だけの演算子、独自の演算子を記述しなければならないユーザー定義型の演算子です。エラーがno match for ‘operator<<’コンパイラがステートメントに対してcout << *temp ;

可能な解決策を<<オペレータを見つけることができなかったと述べている:@ user4581301よう

  1. は、言ったあなたあなたのタイプNodeため<<write your own operatorすることができます。

  2. tempは構造体へのポインタなので、cout << *temp ;文をcout << temp->data ;またはcout << (*temp).data ;に置き換えることもできます。 dataの前に->でアクセスするか、.でアクセスしますが、*オペレータを使用して逆参照してからアクセスできます。

0

いずれの演算子も基本的に関数です。引数は、我々が誤って、オペランド自体を変更しないことを確認するには、ここconstに作られていること、

class Rational 
{ 
    private: 
    ... 
    ... 
    public: 
    ... 
    //Implicit arg "this" is Left Hand operand. 
    //Explicitly stated arg objRational is Right Hand operand. 
    Rational operator+(const Rational& objRational) const {...}; 
    ... 
}; 

は注意してください。例えば 、合理的なクラスのための加算演算子オーバーロードされた演算子+は、メンバ関数として表現されることがありますまた、constというマークを付けて、thisオブジェクトを変更しないようにしています。 Argはrefで渡されます。なぜなら、私たちが確かにそれを変更していなければ、コピーする必要はなく、refに害はないからです。あなたはその後、ちょうど糖衣構文が

Rational r3 = r1 + r2;

と同じコールを許可するためにC++の文法に追加されます

Rational r1(3, 4), r2(22, 7); 
Rational r3 = r1.operator+(r2); //Really possible! Try it! 

ような何かを行うことができますので

上記は、技術的機能であります


あなたが書きました

cout << *temp ;

(*temp)のタイプノードでの

、およびcoutostreamクラスのオブジェクトです。

コンパイラは、左オペランドであるostreamオブジェクトと右オペランドであるNodeオブジェクトを持つオーバーロードされた演算子を探しています。

だから、それは我々が最初の場所でクラスのostreamを書いていないので、我々は、その可能性を持っていない、どこかのクラスのostream自体の内部、

class ostream : ... 
{ 
    ... 
    ... 
    //Here, the only one explicit arg is Node, 
    //which is Right Hand side operand. 
    //Since it is a member operator, 
    //implicit arg "this" will be, by default, the LH operand. 
    public ostream& oprtator<<(const Node& objNode){...} 
    ... 
} 

書き込みと同じくらい良いですが。それが書かれたとき、あなたのノードは存在しませんでした!また、Nodeクラスのメンバーではない関数に対しては許可されないobjNodeのプライベートメンバーにアクセスする必要があるかもしれません。

Nodeクラスのメンバーとして配置しようとすると、Nodeのプライベートメンバーにアクセスできます。しかし、今度はoperator<<の左手オペランドはノードでなければならず、これは目的を全滅させます。

私たちがやっていることは、それを友人の機能にすることです。

class Node 
{ 
    ... 
    ... 
    public: 
    ... 
    //Since this is NOT a member, bot LH and RH operand need to be stated explicitelty 
    friend ostream& operator<< (ostream& out, const Node& objNode) { out << node.data; return out; } 
    ... 
}; 

これはostreamと右オペランドnodeオペランドを残しているし、それは友人だからこれは、ノードのプライベートメンバーにアクセスすることができoperator<<を作成します。 (^_^)

なぜ受け入れと返信 ostreamオブジェクトの参照?

コールをチェーンしようとすると、同じオブジェクトにシリアルに書き込まれる必要があるためです。

文を考えてみましょう:cout << "First: " << objNode1 << ", Second: " << objNode2;

それぞれの呼び出しのために、私たちは以前のすべてを持っているオーバーロードされた演算子に渡されるostreamオブジェクトを必要とし、裏返しから

(
    (
    (
     cout << "First: " //Innermost call 
    ) << objNode1  
) << ", Second: " 
)<< objNode2; 

として評価されます内部コールは、変更された(挿入後の)オブジェクトostreamへの参照を返す必要があります。

希望します。ハッピーコーディング:)

関連する問題