Consider the situation of having some class A together with a factory class Factory. A is supposed to have only private constructors (to prevent the user from creating such an object), and is friends with Factory, who can then construct Objects of type A.
A also has some private attribute which cannot be set in in A's constructor (because the value is not known yet), but will be computed by Factory and then set correctly before A is returned.
Now i have the situation that I have similar classes B,C, ... to A that should also be constructed by Factory, which will thus be a template.
So the situation is currently
template<typename T>
class Factory {
public:
T get() {
T t;
void* computed_value = nullptr; // suppose we compute a
t._value = computed_value;
return t;
}
};
class A {
// Some public methods for the user
friend class Factory<A>;
private:
A() : _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// some more attributes that will correctly be initialsed by the default constructor
};
class B {
//Some public methods for the user
friend class Factory<B>;
private:
B(): _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// Some more attributes that will correctly be initialised by the default constructor
};
void foo() {
Factory<A> a_factory;
A a_elem = a_factory.get();
Factory<B> b_factory;
B b_elem = b_factory.get();
}
Actually, an instance of Factory<A> also stores some values that are used in the construction of some A, that are set by the constructor of Factory, this is why i use instances of the Factory and not static methods.
Now comes the point: I would like to use Concepts in order to constrain the template<typename T> that is used by the Factory, so something like:
template<typename T>
concept Factorable = requires (T t) {
std::same_as<void*, decltype(t._value)>;
};
template<Factorable t>
class Factory { //...
As expected, this does not work, because the corresponding required expressions are private and thus not available, Factorable<A> will just be false.
Now, hanging the attribute and constructor of class A to public will thus lead to a nice generic Factory and the below (correct) code
template<Factorable T>
class Factory {
public:
T get() {
T t;
void* computed_value = nullptr; // suppose we compute a
t._value = computed_value;
return t;
}
};
class A {
// Some public methods for the user
template<Factorable T>
friend class Factory;
public:
A() : _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// some more attributes that will correctly be initialsed by the default constructor
};
class B {
//Some public methods for the user
template<Factorable T>
friend class Factory;
public:
B(): _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// Some more attributes that will correctly be initialised by the default constructor
};
void use() {
Factory<A> a_factory;
A a_elem = a_factory.get();
Factory<B> b_factory;
B b_elem = b_factory.get();
}
Note the subtlety that we now had to declare all generic variants of Factory as a friend of classes A and B, since Factory<A> cannot be evaluated while defining class A itself and thus not explicitly declared as a friend. I am however fine with this, since in the implementation of the Factory<T> we will not access other classes than T anyways (It would however be nice to achieve a friend class Factory<A>, but this is not my priority).
But this approach leads to the massive problem that a user can now generate instances of A by just calling its constructor, which just sets _value = nullptr, so we get 'invalid' instances of A that may lead to undefined behaviour etc. So this is really not the way to go for, although the use of the concepts in above expression would be nice.
So my question now is:
How can I achieve both of the above, in order have private constructors and attributes, but still use concepts
I found out that concepts are actually context-sensitive, in the sense that the required expressions are checked in the invoking context, so in fact the following code will correctly compile
template<typename T>
concept Factorable = requires (T t) {
std::same_as<void*, decltype(t._value)>;
};
template<typename T>
class Factory {
static_assert(Factorable<T>);
public:
T get() {
T t;
void* computed_value = nullptr; // suppose we compute a
t._value = computed_value;
return t;
}
};
class A {
// Some public methods for the user
template<typename T>
friend class Factory;
private:
A() : _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// some more attributes that will correctly be initialsed by the default constructor
};
class B {
//Some public methods for the user
template<typename T>
friend class Factory;
private:
B(): _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// Some more attributes that will correctly be initialised by the default constructor
};
void use() {
Factory<A> a_factory;
A a_elem = a_factory.get();
Factory<B> b_factory;
B b_elem = b_factory.get();
}
since now the compiler will first accept any typename T as generic and then check the concept for the given T within the context of the class, which will thus evaluate to true, since Factory is friends with both A and thus has access to its data members.
So this approach can actually guarantee user-safe instantiation of class A and throwing corresponding errors when the static_assertion fails to evaluate, but of course this is not the way a concept is intended to use, since then we basically just fall back to duck-typing as it was before the introduction of concepts and manually assert certain things, which loses the desired properties of concepts (late error throwing etc., but also losing IDE completion).
A solution would of course be to have the possibility to require the presence of private attributes in a concept, something like the following
//Suppose the existence of a function like std::ignore_private(expression)
template<typename T>
concept Factorable = requires (T t) {
std::same_as<void*, decltype(std::ignore_private(t._value))>;
}
where std::ignore_private is of course completely made up (and i also don't know what syntax it actually should have), but you get the point what i actually want.
So, is there any way to express something like this in a concept?
At least, i could imagine that, since checking for private attributes is a constexpr and can also be checked at compile time.
If you don't find a better solution a compromise could be to constrain the method:
template<typename T>
class Factory {
public:
T get() requires Factorable<T>
{
// ...
}
};
After experimenting around a while, i came up with the following workaround, using an additional Tester class, that has to be declared friend by A:
template<typename T>
concept PrivateFactorable = requires (T t) {
std::same_as<void*, decltype(t._value)>;
};
template<typename T> class Tester {
public:
constexpr static bool factorable = PrivateFactorable<T>;
};
template<typename T>
concept Factorable = Tester<T>::factorable;
template<Factorable T>
class Factory {
public:
T get() {
T t;
void* computed_value = nullptr; // suppose we compute a meaningful value here
t._value = computed_value;
return t;
}
};
class A {
// Some public methods for the user
template<Factorable T>
friend class Factory;
friend class Tester<A>;
public:
A() : _value(nullptr) {} //initialised with nullptr since we have no meaningful value (yet)
void* _value;
// some more attributes that will correctly be initialsed by the default constructor
};
This will correctly redirect Factorable<A> into the tester class, who can evaluate the concept withing friend context with A. The only downside is that A has to have yet another friend (and we get some more concepts in the background), but this seems okay
First, I think it’s a compiler bug if the value of a concept depends on the lexical location of requesting it.
It could interfere with subsumption where that matters, but you can write the constraint directly:
template<class T> requires std::same_as<void*, decltype(T::_value)>
class Factory {…};
Substitution failures in a constraint cause it to be unsatisfied whether it’s in a concept or not.
In the CRTP, I want to inject the constructor into the derived class, cleanly - without use of macros and without writing it out. It seems it's impossible, so I've come up with some workarounds.
First, there's an underlying event class (QEvent) that should have a unique integer type tag for every derived class (see rationale). You obtain it by calling a registration function It's easy enough to create a CRTP wrapper that will hide this from you:
template <typename Derived> class EventWrapper : public QEvent {
public:
EventWrapper() : QEvent(staticType()) {}
static QEvent::Type staticType() {
static QEvent::Type type = static_cast<QEvent::Type>(registerEventType());
return type;
}
};
class MyEvent1 : public EventWrapper<MyEvent1> {}; // easy-peasy
class MyEvent2 : public EventWrapper<MyEvent2> {};
Note that MyEvent1::staticType() != MyEvent2::staticType(): registerEventType() returns unique types each time it's called.
Now I want the event class to carry some data:
template <typename Derived> class StringEvent : public EventWrapper<D> {
std::string m_str;
public:
explicit StringEvent(const std::string & str) : m_str(str) {}
std::string value() const { return m_str; }
};
But here we run into a problem: we need to manually define the constructor in each of the derived classes. The whole point here is that creation of such classes should be easy, as there may be many different string-carrying event types. But it's anything but easy:
class MyEvent3 : public StringEvent<MyEvent3> {
public: MyEvent3(std::string s) : StringEvent(s) {}
};
This obviously gets old real quick, even with C++11 constructor forwarding:
class MyEvent3 : public StringEvent<MyEvent3> { using StringEvent::StringEvent; };
What we'd want is a way of injecting this constructor into the derived class, or avoiding doing so while still providing for ease of use. Sure you can hide it in a preprocessor macro, but I hate those macros, they are a maintenance pain as they introduce new names for very simple concepts.
We can of course use a dummy type. Note that there's no need for a definition of the dummy type. It's only a name to be used as the type argument.
// Pre-C++11
class DummyEvent3;
typedef StringEvent<DummyEvent3> MyEvent3;
// C++11
class DummyEvent3;
using MyEvent3 = StringEvent<DummyEvent3>;
Another solution would be to use an int template argument and use an enum value, but this brings back the uniqueness issue that got solved by using the registerEventType() in the first place. It'd be no fun to guarantee that a large program is correct. And you'd still need to spell out the enum.
So, I've come up with a metaprogram class that I'll call a metafactory, that can produce the ready-to-use StringEvent classes for us, while keeping it all to one type definition:
// the metafactory for string events
template <typename Derived> class StringEventMF {
public:
class Event : public EventWrapper<Derived> {
std::string m_str;
public:
explicit Event(const std::string & val) : m_str(val) {}
std::string value() const { return m_str; }
};
};
or simply
template <typename Derived> class StringEventMF {
public:
typedef StringEvent<Derived> Event;
};
This is used like:
class Update : public StringEventMF<Update> {};
class Clear : public StringEventMF<Clear> {};
void test() {
Update::Event * ev = new Update::Event("foo");
...
}
The classes you use are Update::Event, Clear::Event. The Update and Clear are metafactories: they generate the desired event class for us. The derivation from the metafactory sidesteps derivation from the concrete class type. The metafactory type gives the unique type discriminator needed to create unique concrete class types.
The questions are:
Is there any "cleaner" or "more desirable" way of doing it? Ideally, the following non-working pseudocode would be my ideal way of doing it - with zero repetition:
class UpdateEvent : public StringEvent <magic>;
The name of the derived class appears only once, and the name of the base concept StringEvent appears only once, too. The CRTP requires the class name to appear twice - so far I think it's acceptable, but my metaprogramming-fu is in tatters. Again, I want a preprocessor-less solution, it'd be a no-brainer otherwise.
Is the name metafactory my original invention (ha ha), or is it merely my google-Fu that's lacking? This metafactory pattern seems to be quite flexible. It's easy to compose metafactories by multiple derivation. Say you wanted an Update::Event made by one factory, and Update::Foo made by another.
This question is motivated by this answer. Note: in real code I'd be using QString, but I'm trying to keep it as generic as possible.
I think what you're looking for might be just using placement new to instantiate the base class.
The derived class won't be constructable because unless they will create a matching constructor.
But, they don't have to be constructable, you could use them anyway. (It could still be destructable).
template <class T>
class Base
{
protected: Base(int blah) { }
public: static T* CreateInstance(int data) {
T* newOjectBlock = reinterpret_cast<T*>(::operator new(sizeof(T))); // allocate enough memory for the derived class
Base* newBasePlace = (Base*)(newOjectBlock); //point to the part that is reseved for the base class
newBasePlace= new ((char*)newBasePlace) Base(data); //call the placement new constrcutor for the base class
return newOjectBlock;
}
};
class Derived : public Base<Derived> {}
Then let the CRTP base class construct the derived class like this:
Derived* blah = Derived::CreateInstance(666);
If anyone ever wants to initialize the derived class, they should either make a matching constructor that calls the base class constructor.
OR, just make an .init() method that initiates its members, and will be called after the instance is created.
OR, we can think of something else, this is just an idea of a concept.
Yochai Timmer has come up with an alternative way of approaching the problem. Instead of having to forward the constructor from the data carrier class, he exposes a factory method that produces pseudo-derived classes. As it invokes undefined behavior, I'm not particularly keen on it.
Expanding a bit on the original metafactory concept, it's possible to make generic metafactory that can be used to make unique event types that wrap "any" data-carrying class.
The approach for C++11 uses constructor forwarding so that plain non-template data carrier classes can be used. The approach for C++98 requires a templated data carrier class and, internally, a bit more gymnastics, but it works as well.
The event classes can't be further derived from. This is necessary since the derived classes would all share the value of staticType, and that can't be allowed, as DyP duly noted in the comments.
To test the code, you need the event wrapper, the metafactory and data carrier selected for your variant of C++, and the test/usage part.
The Event Wrapper (Common Code)
In either case, our basic event wrapper CRTP class that generates a unique static type value for the event is:
// A type-identifier-generating wrapper for events. It also works with RTTI disabled.
template <typename Derived> class EventWrapper : public QEvent {
public:
EventWrapper() : QEvent(staticType()) {}
static QEvent::Type staticType() {
static QEvent::Type type = static_cast<QEvent::Type>(registerEventType());
return type;
}
static bool is(const QEvent * ev) { return ev->type() == staticType(); }
static Derived* cast(QEvent * ev) { return is(ev) ? static_cast<Derived*>(ev) : 0; }
};
Note that it also provides a cast-to-derived method. You'd use it in an event handler, given a pointer to a base event class:
void MyClass::customEvent(QEvent* event) {
if (MyEvent::is(event)) {
auto myEvent = MyEvent::cast(event);
// use myEvent to access data carrying members etc)
}
}
The C++98 Metafactory
The Carrier is a parametrized data carrier class, such as StringData below.
// The generic event metafactory
template <typename Derived, template <typename> class Carrier> class EventMF {
class EventFwd;
class Final;
class FinalWrapper : public EventWrapper<EventFwd>, public virtual Final {};
public:
// EventFwd is a class derived from Event. The EventWrapper's cast()
// will cast to a covariant return type - the derived class. That's OK.
typedef Carrier<FinalWrapper> Event;
private:
class EventFwd : public Event {};
class Final {
friend class FinalWrapper;
friend class Carrier<FinalWrapper>;
private:
Final() {}
Final(const Final &) {}
};
};
The EventFwd class is needed so that we have something sane to pass to the EventWrapper template as the derived class, so that the cast() static method will work. The FinalWrapper is there since in pre-C++11 we can't friend typecasts.
Now for the parametrized data carrier. It'd be the same as for the C++11 variant below except for needing to have a parametrized base class.
// A string carrier
template <typename Base> class StringData : public Base {
QString m_str;
public:
explicit StringData(const QString & str) : m_str(str) {}
QString value() const { return m_str; }
};
The C++11 MetaFactory
// The generic metafactory for unique event types that carry data
template <typename Derived, class Data> class EventMF {
class Final;
EventMF();
EventMF(const EventMF &);
~EventMF();
public:
class Event : public EventWrapper<Event>, public Data, private virtual Final {
public:
template<typename... Args>
Event(Args&&... args): Data(std::forward<Args>(args)...) {}
};
private:
class Final {
friend class Event;
private:
Final() {}
Final(const Final &) {}
};
};
The gymanstics with forward-declaration of the Final class are there since forward-declaring the Event class is more typing.
The data carrier is as simple as it gets:
// A string carrier
class StringData {
QString m_str;
public:
explicit StringData(const QString & str) : m_str(str) {}
QString value() const { return m_str; }
};
Usage & Tests (Common Code)
And now we can use the generic metafactory to make some concrete metafactories, and then to make the event classes we need. We create two unique event types that carry the data. Those event classes have unique staticType()s.
// A string event metafactory
template <typename Derived> class StringEventMF : public EventMF<Derived, StringData> {};
class Update : public EventMF<Update, StringData> {}; // using generic metafactory
class Clear : public StringEventMF<Clear> {}; // using specific metafactory
#if 0
// This should fail at compile time as such derivation would produce classes with
// duplicate event types. That's what the Final class was for in the matafactory.
class Error : public Update::Event { Error() : Update::Event("") {} };
#endif
int main(int, char**)
{
// Test that it works as expected.
Update::Event update("update");
Clear::Event clear("clear");
Q_ASSERT(Update::Event::staticType() != Clear::Event::staticType());
Q_ASSERT(Update::Event::staticType() == Update::Event::cast(&update)->staticType());
qDebug() << Update::Event::cast(&update)->value();
Q_ASSERT(Update::Event::cast(&clear) == 0);
qDebug() << Clear::Event::cast(&clear)->value();
Q_ASSERT(Clear::Event::cast(&update) == 0);
}
Im following Lars Haendel's Functor tutorial on newty.de to setup a callback system. I am a bit confused however and I am hoping someone can assist me.
Here is my Functor template
#include <igameevents.h>
// Abstract Base Class (Functor)
class TBaseCallback
{
public:
// two possible functions to call member function. virtual cause derived
// classes will use a pointer to an object and a pointer to a member function
// to make the function call
virtual void operator()(IGameEvent *pEvent){}; // call using operator
virtual void Call(IGameEvent *pEvent) {}; // call using function
};
// Derived Template Class
template <class TClass> class TEventCallback : public TBaseCallback
{
private:
void (TClass::*funcPtr)(IGameEvent*); // pointer to member function
TClass* thisPtr; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores them in two private variables
TEventCallback(TClass* _thisPtr, void(TClass::*_funcPtr)(const char*))
{ thisPtr = _thisPtr; funcPtr=_funcPtr; };
// override operator "()"
virtual void operator()(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
// override function "Call"
virtual void Call(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
};
What I want to do is basically allow other .dlls to use my HookGameEvent() function, and when a Game Event is called, I can run through a vector||list of my hooks, check if the event name matches, then execute the callbacks as needed. What is confusing me though is how I can store the callback in my HookEvent struct which looks like this.
std::vector<EventHook*> m_EventHooks;
struct EventHook
{
char *name;
EventHookMode mode;
//TEventCallback<IGameEvent*> pEventCallback;
};
I have it commented out for now, but im sure its obvious what im confused on and where I am screwing up. If anyone can provide any assistance it would be much appreciated.
Most people don't understand inheritance. Generally, derived classes are implementation details. The only time you utter their names are to construct them. Furthermore, virtual functions in a base should be private and pure, and should be completely inaccessible in derived classes, it's a design bug in C++ that this isn't enforced.
struct TBaseCallback
void operator()(IGameEvent *pEvent) { _Call(pEvent); };
void Exec(IGameEvent *pEvent) { _Call(PEvent); }
private:
virtual void _Call(IGameEvent *pEvent)=0;
};
struct EventHook
{
char *name;
EventHookMode mode;
TBaseCallback *p;
void dispatch(char *msg; IGameEvent *e) const {
if(strcmp(msg,name)==0) p->Exec(e);
}
};
With this design, it doesn't make any difference what is in classes derived from TBaseCallback, and nor should it. Only the abstraction should ever be publically visible. In normal code this is hard to enforce .. when you're using DLLs to get the derived classes it is absolutely mandatory because the set of derived classes is open/arbitrary/infinite/indeterminate (take your pick).
BTW: when you push this to more complex abstractions you will soon discover why Object Orientation is a broken concept. With DLL loaded derived classes, you simply cannot cheat with dynamic_cast switches (because they're closed/specific/finite/determinate).
The class that is going to do the callbacks should hold a list of Functor objects to be called. These would be your
std::vector<EventHook*> m_EventHooks;
Now the EventHook should have a virtual function:
struct EventHook
{
...
virtual void notifyMe();
}
Then everyone that is interested in getting notified will create his own implementation of the hook:
struct MyEventHook : public EventHook
{
virtual void notifyMe() { ... whatever I want to do in that case ... }
}
Through the wonders of polymorphism, when you then iterate over all elements of your m_EventHooks container and call notifyMe() for those, the correct class' version will be called.
The problem I see (and there could very well be others) is that in pEventCallback's type, the template parameter should be a class type but is actually a pointer type. One fix (without limiting what types the callback wraps) is to use the base type:
struct EventHook
{
char *name;
EventHookMode mode;
TBaseCallback* pCallback;
};
If there's more to TEventCallback's API, and it needs to be accessible through an EventHook, you should move the code in TEventCallback that deals with an object and its method into a separate subclass.
// Example EventCallback that takes other args
class EventCallback : public TBaseCallback {
public:
EventCallback();
EventCallback(const EventArgs& evtArgs);
// EventCallback specific methods ...
virtual EventArgs& args();
virtual const EventArgs& args() const;
}
/* TReturn allows for calling methods with a non-void return. Return value is ignored.
*/
template <class TClass, typename TReturn = void>
class TMethodCallback : public EventCallback
{
private:
typedef TReturn (TClass::*TMeth)(IGameEvent*);
TMeth funcPtr; // pointer to member function
TClass* thisPtr; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores them in two private variables
TMethodCallback(TClass* _thisPtr, TMeth _funcPtr)
{ thisPtr = _thisPtr; funcPtr=_funcPtr; };
// override operator "()"
virtual void operator()(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
// override function "Call"
virtual void Call(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
};
Off-Topic
You might as well make the default implementation of TBaseCallback::Call call TBaseCallback::operator().
void TBaseCallback::Call(IGameEvent *pEvent) { this->operator()(pEvent); };
I think you will be getting a complicated compiler error because you are using T* instead of T in your template instantiation.
Try this:
struct EventHook
{
char *name;
EventHookMode mode;
TEventCallback<IGameEvent> pEventCallback;
};
should compile, if that what you want.
I have a class which has a number of static function to perform some calculation. However, before the calculation, I need to pass in a data to initialize some of the static data members. Currently I have an init(data) function and a clearResource() function which should be called before and after the use of the class. Is there a better way of doing that?
For example:
classA(){
static int a;
static init(int b) {
a = b;
}
static functionA(){
//perform something based on value of a;
switch(a){
}
}
}
int main(){
classA::init(5);
classA::functionA();
}
Thanks
Avoid using static member functions : have your constructor initialize the data and the destructor clear the resources (see RAII). If the existing class cannot be changed, implement a helper class which calls init from its constructor and clearResource from its destructor.
You can use this kind of design
class A()
{
public:
static int a;
static void functionA(int arg = A::a)
{
if(A::a != arg)
A::a = arg;
...
}
};
int A::a = 0;
int main()
{
A::functionA();
}
You should apply the RAII concept: see this and this questions.
Make the member functions and data non-static, initialize in a constructor and free resources in the destructor. This will guarantee the correct sequence of calls: initialize - perform operations - free resources in the client code.
I'd avoid using static members in this case.
This is your problem. You have a class that does processing on some data. That data, for whatever reason, needs to be shared across all instances of this processing class. Ok then, we have a non-static solution!
class Data : boost::noncopyable
{
public:
Data()
{
// initialise all of our data.
}; // eo ctor
}; // eo class Data
Where you instantiate this class is up to you. It could be a member of an application class that is run at start up, or part of some root. It just needs to be accessible and does not need to be static nor a singleton.
class DataProcessor
{
private:
Data& m_Data;
public:
DataProcessor(Data& _data) : m_Data(_data)
{
}; // eo ctor
}; // eo class DataProcessor
Is it possible in C++ to have a member function that is both static and virtual? Apparently, there isn't a straightforward way to do it (static virtual member(); is a compile error), but is there at least a way to achieve the same effect?
I.E:
struct Object
{
struct TypeInformation;
static virtual const TypeInformation &GetTypeInformation() const;
};
struct SomeObject : public Object
{
static virtual const TypeInformation &GetTypeInformation() const;
};
It makes sense to use GetTypeInformation() both on an instance (object->GetTypeInformation()) and on a class (SomeObject::GetTypeInformation()), which can be useful for comparisons and vital for templates.
The only ways I can think of involves writing two functions / a function and a constant, per class, or use macros.
Any other solutions?
No, there's no way to do it, since what would happen when you called Object::GetTypeInformation()? It can't know which derived class version to call since there's no object associated with it.
You'll have to make it a non-static virtual function to work properly; if you also want to be able to call a specific derived class's version non-virtually without an object instance, you'll have to provide a second redunduant static non-virtual version as well.
Many say it is not possible, I would go one step further and say it is not meaningfull.
A static member is something that does not relate to any instance, only to the class.
A virtual member is something that does not relate directly to any class, only to an instance.
So a static virtual member would be something that does not relate to any instance or any class.
I ran into this problem the other day: I had some classes full of static methods but I wanted to use inheritance and virtual methods and reduce code repetition. My solution was:
Instead of using static methods, use a singleton with virtual methods.
In other words, each class should contain a static method that you call to get a pointer to a single, shared instance of the class. You can make the true constructors private or protected so that outside code can't misuse it by creating additional instances.
In practice, using a singleton is a lot like using static methods except that you can take advantage of inheritance and virtual methods.
While Alsk has already given a pretty detailed answer, I'd like to add an alternative, since I think his enhanced implementation is overcomplicated.
We start with an abstract base class, that provides the interface for all the object types:
class Object
{
public:
virtual char* GetClassName() = 0;
};
Now we need an actual implementation. But to avoid having to write both the static and the virtual methods, we will have our actual object classes inherit the virtual methods. This does obviously only work, if the base class knows how to access the static member function. So we need to use a template and pass the actual objects class name to it:
template<class ObjectType>
class ObjectImpl : public Object
{
public:
virtual char* GetClassName()
{
return ObjectType::GetClassNameStatic();
}
};
Finally we need to implement our real object(s). Here we only need to implement the static member function, the virtual member functions will be inherited from the ObjectImpl template class, instantiated with the name of the derived class, so it will access it's static members.
class MyObject : public ObjectImpl<MyObject>
{
public:
static char* GetClassNameStatic()
{
return "MyObject";
}
};
class YourObject : public ObjectImpl<YourObject>
{
public:
static char* GetClassNameStatic()
{
return "YourObject";
}
};
Let's add some code to test:
char* GetObjectClassName(Object* object)
{
return object->GetClassName();
}
int main()
{
MyObject myObject;
YourObject yourObject;
printf("%s\n", MyObject::GetClassNameStatic());
printf("%s\n", myObject.GetClassName());
printf("%s\n", GetObjectClassName(&myObject));
printf("%s\n", YourObject::GetClassNameStatic());
printf("%s\n", yourObject.GetClassName());
printf("%s\n", GetObjectClassName(&yourObject));
return 0;
}
Addendum (Jan 12th 2019):
Instead of using the GetClassNameStatic() function, you can also define the the class name as a static member, even "inline", which IIRC works since C++11 (don't get scared by all the modifiers :)):
class MyObject : public ObjectImpl<MyObject>
{
public:
// Access this from the template class as `ObjectType::s_ClassName`
static inline const char* const s_ClassName = "MyObject";
// ...
};
It is possible!
But what exactly is possible, let's narrow down. People often want some kind of "static virtual function" because of duplication of code needed for being able to call the same function through static call "SomeDerivedClass::myfunction()" and polymorphic call "base_class_pointer->myfunction()". "Legal" method for allowing such functionality is duplication of function definitions:
class Object
{
public:
static string getTypeInformationStatic() { return "base class";}
virtual string getTypeInformation() { return getTypeInformationStatic(); }
};
class Foo: public Object
{
public:
static string getTypeInformationStatic() { return "derived class";}
virtual string getTypeInformation() { return getTypeInformationStatic(); }
};
What if base class has a great number of static functions and derived class has to override every of them and one forgot to provide a duplicating definition for virtual function. Right, we'll get some strange error during runtime which is hard to track down. Cause duplication of code is a bad thing. The following tries to resolve this problem (and I want to tell beforehand that it is completely type-safe and doesn't contain any black magic like typeid's or dynamic_cast's :)
So, we want to provide only one definition of getTypeInformation() per derived class and it is obvious that it has to be a definition of static function because it is not possible to call "SomeDerivedClass::getTypeInformation()" if getTypeInformation() is virtual. How can we call static function of derived class through pointer to base class? It is not possible with vtable because vtable stores pointers only to virtual functions and since we decided not to use virtual functions, we cannot modify vtable for our benefit. Then, to be able to access static function for derived class through pointer to base class we have to store somehow the type of an object within its base class. One approach is to make base class templatized using "curiously recurring template pattern" but it is not appropriate here and we'll use a technique called "type erasure":
class TypeKeeper
{
public:
virtual string getTypeInformation() = 0;
};
template<class T>
class TypeKeeperImpl: public TypeKeeper
{
public:
virtual string getTypeInformation() { return T::getTypeInformationStatic(); }
};
Now we can store the type of an object within base class "Object" with a variable "keeper":
class Object
{
public:
Object(){}
boost::scoped_ptr<TypeKeeper> keeper;
//not virtual
string getTypeInformation() const
{ return keeper? keeper->getTypeInformation(): string("base class"); }
};
In a derived class keeper must be initialized during construction:
class Foo: public Object
{
public:
Foo() { keeper.reset(new TypeKeeperImpl<Foo>()); }
//note the name of the function
static string getTypeInformationStatic()
{ return "class for proving static virtual functions concept"; }
};
Let's add syntactic sugar:
template<class T>
void override_static_functions(T* t)
{ t->keeper.reset(new TypeKeeperImpl<T>()); }
#define OVERRIDE_STATIC_FUNCTIONS override_static_functions(this)
Now declarations of descendants look like:
class Foo: public Object
{
public:
Foo() { OVERRIDE_STATIC_FUNCTIONS; }
static string getTypeInformationStatic()
{ return "class for proving static virtual functions concept"; }
};
class Bar: public Foo
{
public:
Bar() { OVERRIDE_STATIC_FUNCTIONS; }
static string getTypeInformationStatic()
{ return "another class for the same reason"; }
};
usage:
Object* obj = new Foo();
cout << obj->getTypeInformation() << endl; //calls Foo::getTypeInformationStatic()
obj = new Bar();
cout << obj->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo* foo = new Bar();
cout << foo->getTypeInformation() << endl; //calls Bar::getTypeInformationStatic()
Foo::getTypeInformation(); //compile-time error
Foo::getTypeInformationStatic(); //calls Foo::getTypeInformationStatic()
Bar::getTypeInformationStatic(); //calls Bar::getTypeInformationStatic()
Advantages:
less duplication of code (but we
have to call
OVERRIDE_STATIC_FUNCTIONS in every
constructor)
Disadvantages:
OVERRIDE_STATIC_FUNCTIONS in every
constructor
memory and performance
overhead
increased complexity
Open issues:
1) there are different names for static and virtual functions
how to solve ambiguity here?
class Foo
{
public:
static void f(bool f=true) { cout << "static";}
virtual void f() { cout << "virtual";}
};
//somewhere
Foo::f(); //calls static f(), no ambiguity
ptr_to_foo->f(); //ambiguity
2) how to implicitly call OVERRIDE_STATIC_FUNCTIONS inside every constructor?
It is possible. Make two functions: static and virtual
struct Object{
struct TypeInformation;
static const TypeInformation &GetTypeInformationStatic() const
{
return GetTypeInformationMain1();
}
virtual const TypeInformation &GetTypeInformation() const
{
return GetTypeInformationMain1();
}
protected:
static const TypeInformation &GetTypeInformationMain1(); // Main function
};
struct SomeObject : public Object {
static const TypeInformation &GetTypeInformationStatic() const
{
return GetTypeInformationMain2();
}
virtual const TypeInformation &GetTypeInformation() const
{
return GetTypeInformationMain2();
}
protected:
static const TypeInformation &GetTypeInformationMain2(); // Main function
};
No, this is not possible, because static member functions lack a this pointer. And static members (both functions and variables) are not really class members per-se. They just happen to be invoked by ClassName::member, and adhere to the class access specifiers. Their storage is defined somewhere outside the class; storage is not created each time you instantiated an object of the class. Pointers to class members are special in semantics and syntax. A pointer to a static member is a normal pointer in all regards.
virtual functions in a class needs the this pointer, and is very coupled to the class, hence they can't be static.
It's not possible, but that's just because an omission. It isn't something that "doesn't make sense" as a lot of people seem to claim. To be clear, I'm talking about something like this:
struct Base {
static virtual void sayMyName() {
cout << "Base\n";
}
};
struct Derived : public Base {
static void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
Derived::sayMyName(); // Also would work.
}
This is 100% something that could be implemented (it just hasn't), and I'd argue something that is useful.
Consider how normal virtual functions work. Remove the statics and add in some other stuff and we have:
struct Base {
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
}
This works fine and basically what happens is the compiler makes two tables, called VTables, and assigns indices to the virtual functions like this
enum Base_Virtual_Functions {
sayMyName = 0;
foo = 1;
};
using VTable = void*[];
const VTable Base_VTable = {
&Base::sayMyName,
&Base::foo
};
const VTable Derived_VTable = {
&Derived::sayMyName,
&Base::foo
};
Next each class with virtual functions is augmented with another field that points to its VTable, so the compiler basically changes them to be like this:
struct Base {
VTable* vtable;
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
VTable* vtable;
void sayMyName() override {
cout << "Derived\n";
}
};
Then what actually happens when you call b->sayMyName()? Basically this:
b->vtable[Base_Virtual_Functions::sayMyName](b);
(The first parameter becomes this.)
Ok fine, so how would it work with static virtual functions? Well what's the difference between static and non-static member functions? The only difference is that the latter get a this pointer.
We can do exactly the same with static virtual functions - just remove the this pointer.
b->vtable[Base_Virtual_Functions::sayMyName]();
This could then support both syntaxes:
b->sayMyName(); // Prints "Base" or "Derived"...
Base::sayMyName(); // Always prints "Base".
So ignore all the naysayers. It does make sense. Why isn't it supported then? I think it's because it has very little benefit and could even be a little confusing.
The only technical advantage over a normal virtual function is that you don't need to pass this to the function but I don't think that would make any measurable difference to performance.
It does mean you don't have a separate static and non-static function for cases when you have an instance, and when you don't have an instance, but also it might be confusing that it's only really "virtual" when you use the instance call.
Well , quite a late answer but it is possible using the curiously recurring template pattern. This wikipedia article has the info you need and also the example under static polymorphism is what you are asked for.
This question is over a decade old, but it looks like it gets a good amount of traffic, so I wanted to post an alternative using modern C++ features that I haven't seen anywhere else.
This solution uses CRTP and SFINAE to perform static dispatching. That, in itself, is nothing new, but all such implementations I've found lack strict signature checking for "overrides." This implementation requires that the "overriding" method signature exactly matches that of the "overridden" method. This behavior more closely resembles that of virtual functions, while also allowing us to effectively overload and "override" a static method.
Note that I put override in quotes because, strictly speaking, we're not technically overriding anything. Instead, we're calling a dispatch method X with signature Y that forwards all of its arguments to T::X, where T is to the first type among a list of types such that T::X exists with signature Y. This list of types considered for dispatching can be anything, but generally would include a default implementation class and the derived class.
Implementation
#include <experimental/type_traits>
template <template <class...> class Op, class... Types>
struct dispatcher;
template <template <class...> class Op, class T>
struct dispatcher<Op, T> : std::experimental::detected_t<Op, T> {};
template <template <class...> class Op, class T, class... Types>
struct dispatcher<Op, T, Types...>
: std::experimental::detected_or_t<
typename dispatcher<Op, Types...>::type, Op, T> {};
// Helper to convert a signature to a function pointer
template <class Signature> struct function_ptr;
template <class R, class... Args> struct function_ptr<R(Args...)> {
using type = R (*)(Args...);
};
// Macro to simplify creation of the dispatcher
// NOTE: This macro isn't smart enough to handle creating an overloaded
// dispatcher because both dispatchers will try to use the same
// integral_constant type alias name. If you want to overload, do it
// manually or make a smarter macro that can somehow put the signature in
// the integral_constant type alias name.
#define virtual_static_method(name, signature, ...) \
template <class VSM_T> \
using vsm_##name##_type = std::integral_constant< \
function_ptr<signature>::type, &VSM_T::name>; \
\
template <class... VSM_Args> \
static auto name(VSM_Args&&... args) \
{ \
return dispatcher<vsm_##name##_type, __VA_ARGS__>::value( \
std::forward<VSM_Args>(args)...); \
}
Example Usage
#include <iostream>
template <class T>
struct Base {
// Define the default implementations
struct defaults {
static std::string alpha() { return "Base::alpha"; };
static std::string bravo(int) { return "Base::bravo"; }
};
// Create the dispatchers
virtual_static_method(alpha, std::string(void), T, defaults);
virtual_static_method(bravo, std::string(int), T, defaults);
static void where_are_the_turtles() {
std::cout << alpha() << std::endl; // Derived::alpha
std::cout << bravo(1) << std::endl; // Base::bravo
}
};
struct Derived : Base<Derived> {
// Overrides Base::alpha
static std::string alpha(){ return "Derived::alpha"; }
// Does not override Base::bravo because signatures differ (even though
// int is implicitly convertible to bool)
static std::string bravo(bool){ return "Derived::bravo"; }
};
int main() {
Derived::where_are_the_turtles();
}
I think what you're trying to do can be done through templates. I'm trying to read between the lines here. What you're trying to do is to call a method from some code, where it calls a derived version but the caller doesn't specify which class. Example:
class Foo {
public:
void M() {...}
};
class Bar : public Foo {
public:
void M() {...}
};
void Try()
{
xxx::M();
}
int main()
{
Try();
}
You want Try() to call the Bar version of M without specifying Bar. The way you do that for statics is to use a template. So change it like so:
class Foo {
public:
void M() {...}
};
class Bar : public Foo {
public:
void M() {...}
};
template <class T>
void Try()
{
T::M();
}
int main()
{
Try<Bar>();
}
No, Static member function can't be virtual .since virtual concept is resolved at run time with the help of vptr, and vptr is non static member of a class.due to that static member function can't acess vptr so static member can't be virtual.
No, its not possible, since static members are bound at compile time, while virtual members are bound at runtime.
If your desired use for a virtual static is to be able to define an interface over the static section of a class then there is a solution to your problem using C++20 concept's.
class ExBase { //object properties
public: virtual int do(int) = 0;
};
template <typename T> //type properties
concept ExReq = std::derived_from<T, ExBase> && requires(int i) { //~constexpr bool
{
T::do_static(i) //checks that this compiles
} -> std::same_as<int> //checks the expression type is int
};
class ExImpl : virtual public ExBase { //satisfies ExReq
public: int do(int i) override {return i;} //overrides do in ExBase
public: static int do_static(int i) {return i;} //satisfies ExReq
};
//...
void some_func(ExReq auto o) {o.do(0); decltype(o)::do_static(0);}
(this works the same way on members aswell!)
For more on how concepts work: https://en.cppreference.com/w/cpp/language/constraints
For the standard concepts added in C++20: https://en.cppreference.com/w/cpp/concepts
First, the replies are correct that what the OP is requesting is a contradiction in terms: virtual methods depend on the run-time type of an instance; static functions specifically don't depend on an instance -- just on a type. That said, it makes sense to have static functions return something specific to a type. For example, I had a family of MouseTool classes for the State pattern and I started having each one have a static function returning the keyboard modifier that went with it; I used those static functions in the factory function that made the correct MouseTool instance. That function checked the mouse state against MouseToolA::keyboardModifier(), MouseToolB::keyboardModifier(), etc. and then instantiated the appropriate one. Of course later I wanted to check if the state was right so I wanted write something like "if (keyboardModifier == dynamic_type(*state)::keyboardModifier())" (not real C++ syntax), which is what this question is asking.
So, if you find yourself wanting this, you may want to rething your solution. Still, I understand the desire to have static methods and then call them dynamically based on the dynamic type of an instance. I think the Visitor Pattern can give you what you want. It gives you what you want. It's a bit of extra code, but it could be useful for other visitors.
See: http://en.wikipedia.org/wiki/Visitor_pattern for background.
struct ObjectVisitor;
struct Object
{
struct TypeInformation;
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v);
};
struct SomeObject : public Object
{
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v) const;
};
struct AnotherObject : public Object
{
static TypeInformation GetTypeInformation();
virtual void accept(ObjectVisitor& v) const;
};
Then for each concrete Object:
void SomeObject::accept(ObjectVisitor& v) const {
v.visit(*this); // The compiler statically picks the visit method based on *this being a const SomeObject&.
}
void AnotherObject::accept(ObjectVisitor& v) const {
v.visit(*this); // Here *this is a const AnotherObject& at compile time.
}
and then define the base visitor:
struct ObjectVisitor {
virtual ~ObjectVisitor() {}
virtual void visit(const SomeObject& o) {} // Or = 0, depending what you feel like.
virtual void visit(const AnotherObject& o) {} // Or = 0, depending what you feel like.
// More virtual void visit() methods for each Object class.
};
Then the concrete visitor that selects the appropriate static function:
struct ObjectVisitorGetTypeInfo {
Object::TypeInformation result;
virtual void visit(const SomeObject& o) {
result = SomeObject::GetTypeInformation();
}
virtual void visit(const AnotherObject& o) {
result = AnotherObject::GetTypeInformation();
}
// Again, an implementation for each concrete Object.
};
finally, use it:
void printInfo(Object& o) {
ObjectVisitorGetTypeInfo getTypeInfo;
Object::TypeInformation info = o.accept(getTypeInfo).result;
std::cout << info << std::endl;
}
Notes:
Constness left as an exercise.
You returned a reference from a static. Unless you have a singleton, that's questionable.
If you want to avoid copy-paste errors where one of your visit methods calls the wrong static function, you could use a templated helper function (which can't itself be virtual) t your visitor with a template like this:
struct ObjectVisitorGetTypeInfo {
Object::TypeInformation result;
virtual void visit(const SomeObject& o) { doVisit(o); }
virtual void visit(const AnotherObject& o) { doVisit(o); }
// Again, an implementation for each concrete Object.
private:
template <typename T>
void doVisit(const T& o) {
result = T::GetTypeInformation();
}
};
With c++ you can use static inheritance with the crt method. For the example, it is used widely on window template atl & wtl.
See https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
To be simple, you have a class that is templated from itself like class myclass : public myancestor. From this point the myancestor class can now call your static T::YourImpl function.
I had a browse through the other answers and none of them seem to mention virtual function tables (vtable), which explains why this is not possible.
A static function inside a C++ class compiles to something which is effectively the same as any other function in a regular namespace.
In other words, when you declare a function static you are using the class name as a namespace rather than an object (which has an instance, with some associated data).
Let's quickly look at this...
// This example is the same as the example below
class ExampleClass
{
static void exampleFunction();
int someData;
};
// This example is the same as the example above
namespace ExampleClass
{
void exampleFunction();
// Doesn't work quite the same. Each instance of a class
// has independent data. Here the data is global.
int someData;
}
With that out of the way, and an understanding of what a static member function really is, we can now consider vtables.
If you declare any virtual function in a class, then the compiler creates a block of data which (usually) precedes other data members. This block of data contains runtime information which tells the program at runtime where in memory it needs to jump to in order to execute the correct (virtual) function for each instance of a class which might be created during runtime.
The important point here is "block of data". In order for that block of data to exist, it has to be stored as part of an instance of an object (class). If your function is static, then we already said it uses the name of the class as a namespace. There is no object associated with that function call.
To add slightly more detail: A static function does not have an implicit this pointer, which points to the memory where the object lives. Because it doesn't have that, you can't jump to a place in memory and find the vtable for that object. So you can't do virtual function dispatch.
I'm not an expert in compiler engineering by any means, but understanding things at least to this level of detail is helpful, and (hopefully?) makes it easy to understand why (at least in C++) static virtual does not make sense, and cannot be translated into something sensible by the compiler.
Maybe you can try my solution below:
class Base {
public:
Base(void);
virtual ~Base(void);
public:
virtual void MyVirtualFun(void) = 0;
static void MyStaticFun(void) { assert( mSelf != NULL); mSelf->MyVirtualFun(); }
private:
static Base* mSelf;
};
Base::mSelf = NULL;
Base::Base(void) {
mSelf = this;
}
Base::~Base(void) {
// please never delete mSelf or reset the Value of mSelf in any deconstructors
}
class DerivedClass : public Base {
public:
DerivedClass(void) : Base() {}
~DerivedClass(void){}
public:
virtual void MyVirtualFun(void) { cout<<"Hello, it is DerivedClass!"<<endl; }
};
int main() {
DerivedClass testCls;
testCls.MyStaticFun(); //correct way to invoke this kind of static fun
DerivedClass::MyStaticFun(); //wrong way
return 0;
}
Like others have said, there are 2 important pieces of information:
there is no this pointer when making a static function call and
the this pointer points to the structure where the virtual table, or thunk, are used to look up which runtime method to call.
A static function is determined at compile time.
I showed this code example in C++ static members in class; it shows that you can call a static method given a null pointer:
struct Foo
{
static int boo() { return 2; }
};
int _tmain(int argc, _TCHAR* argv[])
{
Foo* pFoo = NULL;
int b = pFoo->boo(); // b will now have the value 2
return 0;
}