即将推出的读者的结论
函数内部的抽象类不是一个好主意(至少在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 ...... :))。我还复制了项目设置:
以下是代码:
#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;
}
答案 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