CRTP は、コンパイラがチェックできない CRTP クラスの使用に制限を導入します。つまり、タイプ セーフではない可能性があります。以下を例に取ります。
#include <iostream>
using namespace std;
class Base {
public:
virtual ~Base() {}
virtual Base *copy() = 0;
virtual void SayHello() = 0;
};
template <typename Derived>
class BaseCopy: public Base {
public:
virtual Base *copy()
{
return new Derived(static_cast<Derived const&>(*this));
}
};
Base クラスの利用者が使用制限を知らずに宣言した場合
class Bar: public BaseCopy<Bar> { public: void SayHello(void) { cout << "Hello, I am Bar\n";} };
class Foo: public BaseCopy<Bar> { public: void SayHello(void) { cout << "Hello, I am Foo\n";} };
int main(void)
{
Foo *foo = new Foo;
Base *foo2 = foo->copy(); // What is foo2?
foo->SayHello();
foo2->SayHello();
delete foo2;
delete foo;
return 0;
}
これを例えばでコンパイルします。g++
g++ -Wall -g main.cpp -o CRTP-test.exe
問題なくコンパイルされますfoo->copy();
が、結果が Foo から構築された Bar になるため、呼び出すと未定義の動作が呼び出されます。
//jk