纯虚函数=未引用的局部变量警告
Pure virtual function = unreferenced local variable warning
给即将到来的读者的结论
函数内部的抽象类不是一个好主意(至少在VS2013 Update 3中,它可能是一个bug)。参见编辑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
- 将警告视为错误:Yes/WX
- 优化:Disabled/Od
- 最小重建:Enabled/Gm
- RTTI: No/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来说,如果我将类从主函数中移出,警告就会消失。然而,我不知道为什么我错了,如果我在主函数内定义这些类。所以下面的代码编译时没有任何警告:
#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;
}
我认为问题在于您将类声明为局部函数,没有机会让任何人继承BaseFoo
并覆盖其doIt()
方法。
试试这个:
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
相关文章:
- 警告 C4101 未引用的局部变量
- libmysql:警告:返回局部变量"行"的地址(C++/C)
- 为什么 ++ 运算符触发器返回对局部变量警告的引用
- 三元运算符:编译器不发出局部变量警告的返回引用
- 为什么 C++ 编译器不警告返回对局部变量的引用
- 警告:返回局部变量'buffer'地址
- 没有返回对局部变量的引用的编译器警告
- 警告:返回局部变量"角度"的地址 [-Wreturn-local-addr]
- 警告 C4700:未初始化的局部变量
- 为什么编译器在返回对局部变量的局部引用时不警告"returning address of local variable or temporary"?
- 在 catch 块中使用 g++ 或 clang++ 启用未引用的局部变量警告
- 编译器警告 re:对局部变量的引用
- 将未初始化的局部变量传递给函数时,C++编译器警告(?)
- 警告 C4700:使用未初始化的局部变量"p"
- 纯虚函数=未引用的局部变量警告
- 非局部变量在c++中使用匿名类型警告
- 捕获带有未引用局部变量警告的异常
- 禁用局部变量的未初始化警告
- 如何在g++中设置警告,以警告返回指向局部变量的指针
- GCC 中的断言和未使用的局部变量警告不能很好地混合?