同じコードをコピーして貼り付けるという忙しい作業を減らす方法として、私は暗黒面に目を向け、マクロを使用してそれを行いました。
これが元になっている製品コードははるかに大きく、このようなマクロが役に立たないと、タスクははるかに苦痛になることに注意してください。具体的には、単一の文字列によって駆動される静的関数と仮想関数の組み合わせです。
マクロが問題を引き起こす可能性があることはわかっています。この方法でマクロを使用するのはかなり「臭い」ので、もっと良いものが欲しいのですが、次のように簡単で簡潔なものを思い付くのに苦労しています。
#define LAZY(name)\
static const char * identify() { return name; }\
virtual const char * getName() { return identify(); }
class A{
public:
LAZY("class A")
void foo(){
std::cout << getName() << std::endl;
}
};
class B: public A{
public:
LAZY("class B")
};
std::string somevar( B::identify() );
int main(void){
B b1;
B.foo();
}
私が取った他のアプローチのいくつか (およびそれらが失敗した理由) を以下に示します。
template<class T>
class Base{
public:
virtual const char * getName(){ return T::identify(); }
// All other functions driven by string. IE:
static void register(){ someFactory::reg( T::identify() ); }
virtual unsigned int getHash(){ return someHashFoo( T::identify() ); }
};
class A: public Base<A> {
public:
static const char * idenfity(){ return "class A"; }
void foo(){ std::cout << getname() << std::endl; }
};
class B: public A, public Base<B> {
// Conflict due to multi-inheritance.
};
インスタンスごとにメモリを浪費し、少し複雑なために失敗した別のアプローチ:
class FaceBase{
public:
virtual const char * getName() =0;
};
template<class T>
class ImplBase: public FaceBase {
public:
virtual const char * getName(){ return T::identify(); }
};
class A{
public:
FaceBase & common;
static const char * identify(){ return "class A"; }
A(): common(ImplBase<A>()){}
virtual void foo(){ std::cout << common.getName() << std::endl; }
};
class B: public A{
static const char * identify(){ return "class B"; }
B(){ common = ImplBase<B>(); }
};