Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ design with static methods

Tags:

c++

static

I would like to define as class X with a static method:

class X
{
 static string get_type () {return "X";}
 //other virtual methods
}

I would like to force classes which inherit from X to redefine the get_type() method and return strings different from "X" (I am happy if they just redefine get_type for now).

How do I do this? I know that I cannot have virtual static methods.

Edit: The question is not about the type_id, but in general about a static method that should be overriden. For example

class X {
 static int getid() {return 1;}
}
like image 528
user231536 Avatar asked May 14 '10 18:05

user231536


2 Answers

template<int id>
class X {
public:
    static int getid() { return id; }
};

class Y : public X<2> {
};

You haven't overridden the method, but you've forced every subclass to provide an ID. Caveat: I haven't tried this, there might be some subtle reason why it wouldn't work.

like image 53
Mark Ransom Avatar answered Sep 30 '22 19:09

Mark Ransom


If I'm not mistaken, to call the static method, you have to invoke the method by specifying the exact name of the class, e.g X::get_type();, DerivedClass::get_type() etc and in any case, if called on an object, the dynamic type of the object is not taken into account. So at least in the particular case, it will probably only be useful in a templated context when you are not expecting polymorphic behavior.

However, I don't see why it shouldn't be possible to force each interesting class (inherited or not, since "compile-time polymorphism" doesn't care) to provide this functionality with templates. In the following case, you must specialize the get_type function or you'll have a compile-time error:

#include <string>

struct X {}; 
struct Derived: X {};

template <class T> std::string get_type() {
    static_assert(sizeof(T) == 0, "get_type not specialized for given type");
    return std::string(); 
}

template <> std::string get_type<X>() {
    return "X"; 
}

int main() {
    get_type<X>();
    get_type<Derived>(); //error 
}

(static_assert is C++0x, otherwise use your favourite implementation, e.g BOOST_STATIC_ASSERT. And if you feel bad about specializing functions, specialize a struct instead. And if you want to force an error if someone accidentally tries to specialize it for types not derived from X, then that should also be possible with type_traits.)

like image 44
UncleBens Avatar answered Sep 30 '22 17:09

UncleBens