2016-10-27 15 views
1

今後の読者のために結論純粋仮想関数=参照されていないローカル変数の警告

関数内で抽象クラスは、(少なくともVS2013アップデート3で、それはバグかもしれません)良いアイデアではありません。詳細は編集3とLeonの答えを参照してください。

オリジナルポスト

私はこの警告をやったことがなかったと私は何が起こっているのか見当がつかない。私は警告をエラーとして扱うように私のプロジェクトを設定しました。

class BaseFoo 
{ 
public: 
    virtual ~BaseFoo() = default; 

    virtual void doIt(const std::string& x, const uint8 y) = 0; 
}; // class BaseFoo 

class Foo : public BaseFoo 
{ 
    void doIt(const std::string& x, const uint8 y) override 
    { 
    } 
}; // class Foo 

class Executer 
{ 
public: 
    void doIt(BaseFoo* f) 
    { 
     f->doIt("hello", 0); 
     f->doIt("world", 1); 
    } 
}; // class Executer 

Executer exec; 
BaseFoo* f = new Foo(); 
exec.doIt(f); 
delete f; 

MSVC(VS2013アップデート3)は言う:C4101警告

: 'をBaseFoo ::のdoIt':参照されていないローカル変数

がどのように純粋仮想関数は、「ローカル参照されていないことができます変数 "?私はジャガイモでなければならないか、コンパイラのバグを見つけましたか?

編集:私はFoo::doIt機能(例えばSTD :: coutの)にコードを配置する場合

、何も変わりません。

BaseFoo::doItを非純粋な「単純な」仮想関数に変更すると、何も行われず警告が消えます。

編集2:コンパイル可能な単一のファイル

だから私は、コンパイル可能主な機能(私が知っている、ARGV、argcの、MEH ... :))に "コピー&ペースト" のコードをしました。レベル3の警告

  • ::私はまた、プロジェクトの設定をコピーしたエラーなど/ W3
  • トリート警告:はい/ WX
  • 最適化:有効/ Gmの
  • :/ OD
  • 最小限の再構築を無効
  • RTTI:いいえ/ GR-

そして、ここではコードです:

#include <iostream> 
#include <string> 

typedef unsigned __int8 uint8; 

int main() 
{ 
    class BaseFoo 
    { 
    public: 
     virtual ~BaseFoo() = default; 

     virtual void doIt(const std::string& x, const uint8 y) = 0; 
    }; // class BaseFoo 

    class Foo : public BaseFoo 
    { 
     void doIt(const std::string& x, const uint8 y) override 
     { 
      std::cout << x << y; 
     } 
    }; // class Foo 

    class Executer 
    { 
    public: 
     void doIt(BaseFoo* f) 
     { 
      f->doIt("hello", 0); 
      f->doIt("world", 1); 
     } 
    }; // class Executer 

    Executer exec; 
    BaseFoo* f = new Foo(); 
    exec.doIt(f); 
    delete f; 

    return 0; 
} 

編集3:

ポイントは、私は、main関数からクラスを移動した場合、警告は消え、レオンのために行きます。しかし、主な機能の中でこれらのクラスを定義するとどうして私が間違っているのか分かりません。だから、次のコードは警告なしにコンパイルされます。

#include <iostream> 
#include <string> 

typedef unsigned __int8 uint8; 

class BaseFoo 
{ 
public: 
    virtual ~BaseFoo() = default; 

    virtual void doIt(const std::string& x, const uint8 y) = 0; 
}; // class BaseFoo 

class Foo : public BaseFoo 
{ 
    void doIt(const std::string& x, const uint8 y) override 
    { 
     std::cout << x << y; 
    } 
}; // class Foo 

class Executer 
{ 
public: 
    void doIt(BaseFoo* f) 
    { 
     f->doIt("hello", 0); 
     f->doIt("world", 1); 
    } 
}; // class Executer 

int main() 
{ 
    Executer exec; 
    BaseFoo* f = new Foo(); 
    exec.doIt(f); 
    delete f; 

    return 0; 
} 
+1

はmain' '内の最後のビットを置くことの明らかな変化とVS2013でREPROすることはできません。完全なコンパイル可能な例を投稿し、使用しているVSのバージョンを教えてください。 – molbdnilo

+0

このコードでは、私は期待している/ W4のxとyの「参照されていない仮パラメータ」しか得ていません(MSVC 2013) – axalis

+0

vs2015のReproはありません – George

答えて

2

私は問題はあなたが誰もがBaseFooを継承し、そのdoIt()メソッドをオーバーライドするためにはチャンスを残さない、関数にローカルとしてあなたのクラスを宣言することだと思います。

+0

ローカルから関数へのクラスはすべて、 'MCVE'リクエストの一部です。 – StoryTeller

+0

実際これが問題でした。これらのクラスをメイン関数から移動すると、警告は消えます。しかし、FooはBaseFooから継承しているので、これはとにかく動作するはずです。これはバグになっていますか? – csisy

+0

@csisy警告にバグとしてラベルを付けるべきではないと思います。抽象クラスはそれがローカルであるかどうかにはあまり意味がありません。抽象クラスは、それらをサブクラス化することを奨励する目的で導入されており、関数内に隠れていると不可能です。 – Leon

1

はこれを試してみてください:

class BaseFoo 
{ 
public: 
    virtual ~BaseFoo() = default; 

    // As a pure-virtual is intrinsically a "do-nothing" 
    // the name of the parameters doesn't matter for the compiler 
    virtual void doIt(const std::string& /* x */, const uint8 /* y */) = 0; 
}; // class BaseFoo 

class Foo : public BaseFoo 
{ 
    // Other compilers are even Nazi-er than VS and emit a whinge... 
    // errr, pardon my mouth, I meant to say... 
    // a warning for any unused parameter ('g++ -Wall', I'm looking at you)   
    // The same works too for keeping them happy and silent. 
    void doIt(const std::string& /* x */, const uint8 /* y */) override 
    { 
    } 
}; // class Foo 
+0

これらのクラスを(私のOPのように)メイン関数の内部に置いておくと、問題は続くのですが、警告はdoIt関数自体であり、パラメータは残念です。しかし、チップのおかげで! – csisy

+0

"警告はdoIt関数自体についてであり、残念なことにそのパラメータではありません。ああ、そうです。知っておいてよかった。 –

関連する問題