Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
210 views
in Technique[技术] by (71.8m points)

c++ - Avoiding virtual methods in constructor

Say I have the following class hierarchy:

class Base
{
   virtual int GetClassID(){ return 0;};
public:
   Base() { SomeSingleton.RegisterThisObject(this->GetClassID());
}

class Derived
{
   virtual int GetClassID(){ return 1;};
public:
   Derived():Base(){};
}

Well, it's all simplified from my real case, but that's the general gist of it.

I want to avoid having to call RegisterThisObject in the constructor of each derived class, so I'm trying to move the call to the constructor of the base class.

Is there any pattern that I can use to acomplish this without using the virtual method in the constructor?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You might use the Curiously Recurring Template Pattern

template <class T>
class Base
{
protected:  // note change
   Base() { SomeSingleton.RegisterThisObject(T::GetClassID());
}

class Derived : Base<Derived>
{
   static int GetClassID(){ return 1;};
public:
   Derived(): Base<Derived>(){};
}

Also, it will require extra work when you have multiple generations of derived classes (say DerivedDerived : Derived). I'd suggest you simply avoid that but in other cases you might want to move the registration into a policy class instead (make the behaviour aggregatable as opposed to a part of the class identity)

Traits

Expanding on my hint (make the behaviour aggregatable), you'd see something like this:

namespace detail
{
    template <class T> struct registerable_traits { };         
    template<> struct registerable_traits<Derived>
    { 
        enum _id { type_id = 1 };
    };
}

template <class T>
class Base
{
protected:  // note change
   Base() { SomeSingleton::RegisterThisObject(detail::registerable_traits<T>::type_id); }
};

class Derived : Base<Derived>
{
public:
   Derived(): Base<Derived>(){};
};

See Codepad.org


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...