【发布时间】:2011-03-04 09:06:07
【问题描述】:
我收到一个编译器警告,在这种情况下我不明白。当我从以下代码编译“Child.cpp”时。 (不要奇怪:我将我的类声明剥离到最低限度,所以内容没有多大意义,但你会更快地看到问题)。我收到了最高警告级别的Visual Studio 2003 和Visual Studio 2008 警告。
代码
AbstractClass.h:
#include <iostream>
template<typename T>
class AbstractClass
{
public:
virtual void Cancel(); // { std::cout << "Abstract Cancel" << std::endl; };
virtual void Process() = 0;
};
// Outside definition. If I comment out this and take the inline
// definition like above (currently commented out), I don't get
// a compiler warning.
template<typename T>
void AbstractClass<T>::Cancel()
{
std::cout << "Abstract Cancel" << std::endl;
}
Child.h:
#include "AbstractClass.h"
class Child : public AbstractClass<int>
{
public:
virtual void Process();
};
Child.cpp:
#include "Child.h"
#include <iostream>
void Child::Process()
{
std::cout << "Process" << std::endl;
}
警告
“Child”类派生自“AbstractClass”。在“AbstractClass”中有公共方法“AbstractClass::Cancel()”。如果我在类主体之外定义方法(就像你看到的代码一样),我会收到编译器警告...
AbstractClass.h(7) : 警告 C4505: 'AbstractClass::Cancel' : 未引用的本地函数已被删除 与 [T=int]
...当我编译“Child.cpp”时。这个我不明白,因为这是一个public函数,编译器不知道我以后有没有引用这个方法。最后,我引用了这个方法,因为我在 main.cpp 中调用它,尽管有这个编译器警告,但如果我编译并链接所有文件并执行程序,这个方法仍然有效:
//main.cpp
#include <iostream>
#include "Child.h"
int main()
{
Child child;
child.Cancel(); // Works, despite the warning
}
如果我确实将 Cancel() 函数定义为内联(您将其视为 AbstractClass.h 中的注释代码),那么我不会收到编译器警告。我的程序当然可以工作,但我想了解这个警告还是这只是编译器错误?
此外,如果不将 AbsctractClass 实现为模板类(在这种情况下仅用于测试目的),我也不会收到编译器警告...?
如果我创建一个非虚拟函数,我不会收到该非虚拟函数的编译警告,但到目前为止的所有答案都不包含虚拟内容。试试这个:
template<typename T>
class AbstractClass
{
public:
virtual void Cancel(); // { std::cout << "Abstract Cancel" << std::endl; };
virtual void Process() = 0;
void NonVirtualFunction();
};
//...
template<typename T>
void AbstractClass<T>::NonVirtualFunction()
{
std::cout << "NonVirtualFunction" << std::endl;
}
知道的答案对我有帮助,但我认为问题没有得到完全回答。
【问题讨论】:
-
MSDN 有点解释了下面几篇文章中也解释的内容:msdn.microsoft.com/en-us/library/z85eyax0.aspx
-
但在这种情况下,警告解释对我没有帮助。在任何其他情况下,警告的含义对我来说都很清楚,但在这里我的麻烦是由模板的东西引起的。无论如何感谢您的努力。
-
如果您将
Cancel()标记为inline而将其保留在类定义之外会怎样? -
@sbk:如果我将其标记为内联,但将代码定义保留在外面,我不会收到警告。
-
即使你不使用模板,但你不使用内联方法,我想如果你在Child.h之外的其他文件中使用AbstractClass.h,你可能会遇到一些错误。例如,另一个文件 AnotherChild.h 包含 AbstractClass.h,它也包含在 main.cpp 中。
标签: c++ templates compiler-warnings base-class