Last year I saw some source code (C++) where its author declares static function in base class, but leaves its definition to derived class. I remember there was constraint that only one derived class was permitted to define aforementioned static function.
I know that it is impossible to override static methods, but this trick is exactly what I need. I just can't make it work in my code :) Does an开发者_开发知识库yone know about this feature?
Lets look why this would be useful. Suppose we have some base class (Shape), and its derived classes (Circle, Triangle...). Suppose Shape is part of my core architecture, and derived classes are treated as plugins. I don't want to change my core architecture in future. So we have:
class Shape
{
//other stuff here
static Shape* Factory();
}
class Circle:Shape
{
//other stuff here
static Shape* Factory();
}
Shape is sort of abstract class, and it will not implement Factory method. Method is implemented by one (and only one) of the derived classes. In implementation derived class will return new instance of itself, so it is just a factory method. This trick allowed its author to use this static method in client class in following way:
class Client
{
public Shape* shape;
public Client();
//other stuff here
}
In implementation of constructor he had something like:
Client::Client()
:shape(Shape::Factory())
{
}
This way he was able to instantiate "right" shape derivation without changing core classes in engine. When he wanted some other shape to be used in core classes he just had to define static Factory method in that derived class (and to remove the existing one in other derived class).
This way we have some sort of "static polymorphism". I can't find anything about this technique on the web. Does it even have a name? I am especially interested if something like this could be achieved in C# language? :)
Thanks in advance, and sorry for my bad English.
What it sounds like you are trying to do is a bit messy in my opinion. It feels like a combination of a Factory class, a Singleton and then trying to squish them all back into your result class hierarchy.
The simplest (not necessarily the best) solution I can think of is forget about having either Circle::Factory()
or Shape::Factory()
and just have a free function called get_default_shape()
.
class Shape
{
};
class Circle: public Shape
{
};
Shape * get_default_shape()
{
return new Circle;
}
Client::Client()
:shape(get_default_shape())
{
}
The nice bit about this is that its only the implementation of get_default_shape that needs to include Circle.h, all the definition needs is a forward declaration of the Shape class.
Hmm. I have not seen exactly what you describe. It could be that the piece of code you refer to defined the base class static function in the cpp file containing your derived class.
// definition of Circle class
.....
Shape* Shape::Factory()
{
return new Circle();
}
This is not useful in this example but it could be a useful trick if you want to hide the implementation of a class and only publish an abstract base class (to reduce compile time dependencies). It won't work if the base and derived classes are not in the same dll/exe.
Similar things can be achieved in C# by using an IOC framework, with generics, or by registring a factory delegate
in your base class. I tend to prefer generics and delegates.
精彩评论