3

私はこれに頭を悩ませてきました、そして他のすべての投稿をふるいにかけた後、私は途方に暮れてしまったと思います。

C ++でテンプレートコーディングと演算子のオーバーロードを練習したいと思ったので、迅速で汚いLinkListの実装はかなりうまくいくと思いました。次のように、ノードとリストのクラスセットをすばやくハックしました。

template <class T>
class Node{
public:
  Node* getNext(){ return Next; }

private:
  Node* Next;
  T data;
};

template <class T>
class List{
public:
  List& operator++();

private:
  Node<T>* nptr;
};

template <class T>
List<T>& List<T>::operator++(){
  if( nptr->getNext() ){
    nptr = nptr->getNext();
  }
  return *this;
}

main call:
int main(){
  List<int>* listObj = new listObj<int>();
  ...push on some nodes with random values...
  ++listObj;
  KABOOM
}

読みやすくするために、コードは簡潔にしています。ノードを作成するときに常にNextをNULLに初期化し、最後にノードを追加するプッシュ関数があり、最後のノードの「Next」変数をその新しいノードに設定し、nptrもNULLとして初期化を開始するとします。 。すべての「想定される」機能(構築、初期化、ノードのプッシュ)をテストし、operator++関数を単なる増分関数としてパックすることもできます...

void Increment(){
  if( nptr->getNext() ){
    nptr = nptr->getNext();
  }
}

call:
listObj->Increment();

...そしてそれはうまく機能します。言い換えれば、コンパイラは私のバージョンの++ fooをコード内のどの用途にも割り当てていません!デバッガーを使用してこれを証明することもできます。これは、必要に応じてnptrを更新するのではなく、Listオブジェクトのアドレスをインクリメントするのを監視します。

さて、私はここで関数を友達にするという提案を見て、試してみました:

friend List& operator++(){
  if( nptr->getNext() ){
    nptr = nptr->getNext();
  }
  return *this;
}

ただし、そうすると、コンパイルエラーが発生します。

List& operator++() must have an argument of class or enumerated type

私は頭の固いプログラマーであり、当然のことながら機能しなかった着信RHSを調査する必要があると考えました。私はそれが正しい方向ではなかったとかなり確信しているので、私はその壊れた推論の道を書き出すのを控えています。

コンパイラが私のコードに満足しているように見える(または少なくとも実際にはどこにも割り当てられていないために動揺していない)のに、なぜそれでもテンプレート化されていないバージョンの演算子を取得してintのように扱うのですか?コンパイラが提供された関数を代わりに使用できるようにコードを修正するにはどうすればよいですか?

前もって感謝します!

4

1 に答える 1

3

ユーザー定義の演算子は、ポインターなどの組み込み型には適用できません。Listどちらかといえば、インクリメント演算子を使用する前に、ポインタを逆参照する必要があります。

++*listObj;

組み込みのインクリメント演算子がない*場合、これは明らかにあなたが望むものではありません。ただし、実際にはポインタを逆参照していると思いますKABOOM。通常、問題が発生した場所を正確にコードで示し、実際に問題が発生した場所をより正確に示したいと考えています。また、引用したものではなく、実際にコンパイルコードを作成したと仮定しています...

于 2012-09-17T06:41:24.397 に答える