そのコンテキストでは理解できないというコンパイラ警告が表示されます。次のコードから「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」をコンパイルすると。これはパブリック関数であり、コンパイラは後でこのメソッドを参照するかどうかを判断できないため、これを理解できません。最後に、このメソッドを参照します。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;
}
知っている限りの答えは役に立ちましたが、質問が完全に答えられているとは思いません。