2010-12-01 11 views
4

仮想として宣言された関数のために、廃止された警告が表示されることがあります。 「g ++(GCC)4.1.1 20061011(Red Hat 4.1.1-30)」を使用しています。 私の研究は、 純粋な仮想関数(すなわち、クラスbueller {仮想int cameron()= 0;};)を非難することに関するgcc 4.xに問題があるかもしれないことを示しています。それらを通常の仮想関数と呼んでください。 ただ、私たちが同じページにしている...g ++を使用して、仮想クラスメンバ関数を非推奨にする方法

がfoo.h

class Foo 
{ 
    void Foo_A() __attribute__((deprecated)); //non-virtual 
    virtual void Foo_B() __attribute__((deprecated)); //virtual 
    virtual void Foo_C() __attribute__((deprecated)) = 0; //pure virtual 
}; 

言って、私はこれをコンパイルし、foo.cppファイルや++グラムを使用して、いくつかのmain.cppにファイル。

1)Foo_A()を使用するものはいずれも実際に警告を表示します。

2)Foo_B()を使用するものは警告を表示しません。

3)Fooを継承し、Foo_Cを実装し、それを使用して警告を表示しないもの。

番号1:問題なく動作します。

番号3:どんな..既知のバグ/機能のように思える。..

は、しかし、2位にはexplinationはないように思えます。 おそらくそれは#3で結ばれていますが、私が見つけたものは何も言及していません。

ここで、私が廃止予定の通常の仮想クラスメンバー機能に関して何か不足していることを知っている人は誰ですか?

BTW:私のmakefileで-Wno-deprecateが有効になっていません。

答えて

1

g++  deprecate.cc -o deprecate 
deprecate.cc: In function ‘int main()’: 
deprecate.cc:14: warning: ‘Foo_B’ is deprecated (declared at deprecate.cc:3) 
:CentOSの5.2(gccのバージョン4.1.2 20080704(Red Hatの4.1.2-44))で

struct Foo 
{ 
    virtual void Foo_B() __attribute__((deprecated)); //virtual 
}; 

struct DerivedFoo : public Foo 
{ 
}; 


int main() 
{ 
    DerivedFoo d; 
    d.Foo_B(); 
    Foo &f = d; 
    f.Foo_B(); 
} 
void Foo::Foo_B() {} 

は、私はあなたが記述と同じ出力を得ます

しかし、Ubuntuの10.04.1(gccのバージョン4.4.3(Ubuntuの4.4.3-4ubuntu5))上で、私はあなたが期待する出力を得る:だから

g++  deprecate.cc -o deprecate 
deprecate.cc: In function ‘int main()’: 
deprecate.cc:14: warning: ‘virtual void Foo::Foo_B()’ is deprecated (declared at deprecate.cc:3) 
deprecate.cc:16: warning: ‘virtual void Foo::Foo_B()’ is deprecated (declared at deprecate.cc:3) 

を、私はそれを推測していますコンパイラのバグが修正されました。

+0

Rob、動的メモリと - >演算子を使用するとどうなるのでしょうか?オペレーター?それは同じように振る舞いますか?私はgentooを実行していますが、現時点ではUbuntuではありません。 – sbrett

+0

"d"と "f"をポインタに変更し、 ' - > Foo_B()'を呼び出すと、まだ2つの警告が表示されます。 –

+0

Robにお尋ねいただきありがとうございます。また、彼の助けを借りてStaffanにも感謝します。これは欠けている欠点の警告の謎を解決します。それは老人ジョンソンだった。いい仕事チーム! – sbrett

0

Fooポインタ/参照、または派生クラスを通じてFoo_B()/ Foo_C()を呼び出していますか?派生クラスを使用している場合、そのクラスでも非推奨となっているメソッドをマークするか、記述した動作が得られるようです。

+0

私は "Foo"からクラスを派生しているという点では正しいですが、問題の関数を実際に上書きするわけではありません。基本クラスの関数をオーバーライドしなければ、派生クラスのオーバーライド関数を非推奨と宣言する必要はないと思います。つまり、オーバーライドしていないためです。おそらく、それは仮想テーブルになっているのでしょうか?そこでは、基本クラスのFoo :: Foo_B()ではなく、DerivedFoo :: Foo_B()が(DerivedFooクラスで明示的にオーバーライドされていなくても)呼び出されていますか?私は最終的にはどちらも同じ方法に等しいと思う。 – sbrett

+0

しかしそれはまあまあです。あなたが記述する振る舞いは、GCC 4.5.1でも同じです。 GCCのマニュアルはあまり説明していませんが、現在の動作を改善できると思ったら、メーリングリストの1つで質問することをお勧めします。 – Staffan

+0

私はマニュアルの部分であなたに同意します。私はまずそこを見た。私はこれをまっすぐに持っています...あなたは、非推奨の警告メッセージが表示されるために、私はこのような何かをしなければならないと私に言っています... void DerivedFoo :: Foo_B(){Foo :: Foo_B( );}?まあ、まあまあです。私がGCCの人たちが何を考えているのだろうと思っているにもかかわらず、非難された基底関数があれば、あなたは継承し、非推奨の関数をオーバーライドするという警告を吐き出すことが望ましいでしょう。基本クラスポインタからのその関数へのアクセスはBOOMになります。 – sbrett

0

Googleは、このトピックに関する古いdiscussionをDebianリストに示しています。しかし、このトピックについては、最近何も出てこない。ディストリビューション(RedHat's、この場合は)リストを確認してみてください。このプログラムを考える

関連する問題