纯虚函数=未引用的局部变量警告

时间:2016-10-27 12:13:28

标签: c++

即将推出的读者的结论

函数内部的抽象类不是一个好主意(至少在VS2013 Update 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 Update 3)说:

  

警告C4101:'BaseFoo :: doIt':未引用的局部变量

纯虚函数如何成为“未引用的本地变量”?我必须是一个土豆或我发现了编译器错误?

修改

如果我将代码放入Foo::doIt函数(例如std :: cout),则没有任何变化。

如果我将BaseFoo::doIt改为非纯粹的“简单”虚拟函数,它什么也不做,警告就会消失。

编辑2:可编辑的单个文件

所以我将代码“复制粘贴”到可编译的主函数中(我知道,argv,argc,meh ...... :))。我还复制了项目设置:

  • 警告级别3:/ W3
  • 将警告视为错误:是/ WX
  • 优化:已禁用/ Od
  • 最小重建:启用/ Gm
  • 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:

对于Leon来说,如果我从主函数中移出类,警告就会消失。但是,如果我在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;
}

2 个答案:

答案 0 :(得分:2)

我认为问题在于您将类声明为函数的本地类,任何人都无法继承BaseFoo并覆盖其doIt()方法。

答案 1 :(得分: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