2011-08-03 3 views
3

Visual Studio 2008 C++アプリケーションを使用して、カスタムstreambufと​​ストリームのインプリメンテーションを作成しました。私は、以下の詳細な流れを作成するためのAngelika Langerによって与えられたアプローチを使用しました:カスタムstdストリームのインプリメンテーションを作成するときのコンパイラの警告

class MyOutputStream_3 : private MyStreamBuf, public ostream { 
public: 
    MyOutputStream_3() : ostream((MyStreamBuf*) this), ios(0) {}; 
    virtual ~MyOutputStream_3() { sync(); } 
    // ... 
}; 

をしかし、Visual Studioは、私にwarningを与える:コードは正常に動作し

warning C4355: 'this' : used in base member initializer list 

が、私は心配していますコンパイラは、私がやったことが、いくつかの状況下で壊れる可能性があるか、移植性がないかもしれないことを私に知らせる。

これは私がこのインスタンスで無視できるものか、問題を解決するために何をすべきですか?

+1

_Never_警告を無視します。 –

+0

@Tomalak - 指定されたコードが間違っていて、変更しなければならないと言っていますか?もしそうなら、どうですか?または、将来の変更によってコードが間違ってしまう可能性があるため、警告を念頭に置いておくべきですか? – PaulH

+0

まだ私はコードが間違った/未定義であるかもしれない理由を特定することができませんでした。それはそうではないことを意味するわけではなく、あなたのコンパイラは私よりも言語をよく知っています。また、「注意してください;あなたのコードは、わずかな変更でひどく間違って変わる可能性があります!また、警告を無視しないほどの理由もあります。彼らはただの楽しみのために放出されません! [あなたのコードを変更しなければならないと言っているわけではありません。どちらも警告を完全に無視しないでください。どこかに中盤があります。 :)] –

答えて

1

C++ 03標準では "基地とメンバーをInitializaing" 12.6.2/7用のノートで、このビットを持っています

[注:mem-initializerはコンストラクタのスコープ内で評価されるため、このポインタはmem-initializerのexpression-listで初期化されるオブジェクトを参照するために使用できます。 ]

thisポインタで参照されているオブジェクトが完全に初期化されていない可能性があるため、警告が表示されると思います。あなたのベースが実際にでない限り、オブジェクトの初期化されていない部分が初期化されるまで、を使用してください。警告(http://msdn.microsoft.com/en-us/library/3c594ae3.aspx)のためのMSDNドキュメントとして

は言及:

は実際には、あなたは別のコンストラクタにunconstructedオブジェクトへのポインタを渡されました。それらの他のコンストラクタがこれに任意のメンバにアクセスしたりメンバ関数を呼び出すと、結果は未定義になります。

+0

派生したインスタンスが完全に構築される前に 'this'を基本型に変換することがUBだと一度は読んでいます。 –

+0

ちなみに、 '[2003:9.3.2]'は、メンバー初期化子で 'this'の型を実際に定義していないようです。 –

+0

@Tomalak:初期化子リストに表示される 'this'は' D * '型です。構造体D:B {D():B(this){}};'これはC++ 03§12.7/ 2での例ですが、この動作は仮想関数のディスパッチ方法によっても暗示されます。 (私は、標準的なテキストがこれを指定する場所がわからないことを認めています) –

2

それは技術的には、thisはコンストラクタがまだ実行を終了していないので、まだ存在して(でも任意のメンバーオブジェクトのコンストラクタを持って)いないため、初期化子リストでthisの使用に関する警告や関数に渡していますそのオブジェクト(コンストラクタが呼び出されていないオブジェクトを含む)を使用しようとすると問題が発生する可能性があります。

後で使用するためにポインタを格納するだけの場合は、コードが機能するはずです。しかし、このコードに戻って、あなたがそのポインタを使うべきではないことを忘れると、あなたは間違いを犯すかもしれないし、あなたのプログラムがなぜクラッシュするのか説明できないかもしれません。ここで

はその警告のために、Microsoftのページです:http://msdn.microsoft.com/en-us/library/3c594ae3.aspx

0

なお、これはmem-initializerリストに明示的にthisを使用した場合にのみ発生します。まだ構築されていないメンバー変数のアドレスを渡しても、C4355は発生しません。

証明が必要な場合はfstreamのコンストラクタを見てください。

関連する問題