This post is what I just read.
The way he implements Singleton in C++ confuses me. I got several Questions about it and here is his code:
template<typename T>
class Singleton {
public:
static T& getInstance() { //Question 1
return instance;
}
private:
static T instance;
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};
Question
I think we should put the static T& getInstance()'s definition outside of the class body, right?
He tries to make class DebugLog a singleton class, but when he inherits Singleton<DebugLog>, the DebugLog doesn't already exist, right? If right, then how can the template class Singleton instantiate an un-existent class?
1) Nope, it doesn't matter how you structure your code. Singleton isn't a class, by the way: It's a template. Since the full template definition must be visitible at any instantiation site anyway, you might as well define everything inline.
2) class DebugLog : public Singleton<DebugLog> is fine. We are not inheriting from a non-existing class; rather, we are inheriting from the class Singleton<DebugLog>. Templates can be instantiated on incomplete types. (There are several rules what you can and cannot do with such a type parameter.)
For example, template <typename T> class Foo { }; can certainly be instantiated on any type without problem. More interestingly, template <typename T> struct PointerFactory { typedef T * type; }; can be instantiated on any type, complete or not. In the present situation, the purpose of the template parameter in the CRTP is solely to inform the base class of its eventual derived type, so this is entirely fine.
It would certainly be cleaner if the function were defined outside of
the class, and make the code easier to read and to maintain. In this
case, however, the complete class is small enough that the difference
isn't very great, and of course, because we're dealing with a template,
the actual definition still has to be included in every translation unit
which uses it.
The C++ standard doesn't speak of “existence” with regards to classes (or anything
else). At the point of template instantiation, name lookup finds
DebugLog, and finds that it is a class (thus, a type). At that point,
it is an incomplete type, and there are only limited things you can do
with an incomplete type. If the class template which is instantiated
doesn't do anything that requires a complete type (and Singleton
doesn't), then there is no problem. (Note that only the class
definition is instantiated at this point; class member functions will
not be instantiated until they are used.)
I might add that there is still one important thing missing from the
code you posted: there is no definition for the declaration
Singleton::instance. You still need to add a:
template<typename T> T Singleton<T>::instance;
somewhere.
You must use a pointer to T in this case:
template<typename T>
class Singleton {
public:
static T& getInstance() {
static T * instance = NULL;
if (!instance)
instance = new T;
return *instance;
}
};
class DebugLog : public Singleton<DebugLog> { //Question 2
public:
void doNothing() {}
};
Related
I have a question as I cannot explain why something works where I probably have made a mistake. Maybe somebody kind can help me to improve my C++ culture by explaining to me why this is so.
For better transparency I simplifiy the code quite a bit.
I have a template virtual class that is like this:
template<class Node>
class tXmlNode
{
public:
tXmlNode();
virtual ~tXmlNode();
protected:
Node* node;
}
;
From this I derive several classes.
Mostly I derive from it another template class such as this one:
template<class Part>
class tXmlMove : public tXmlNode<Part>
{
public:
tXmlMove(Part* part);
~tXmlMove();
protected:
int n_translate;
};
with this implementation (reduced to the constructor):
template<class Part>
inline tXmlMove<Part>::tXmlMove(Part* part) : tXmlNode<Part>(part)
{
//do some construction
}
;
As you can see I delegate some part of the construction to the parent class constructor. Works fine.
Now I have another derived class but which is derived from a specialized parent class (the specialisation is a self-specialisation but from other classes with similar specialized parent it works exactly as for this one):
class tXmlCaseDefinition : public tXmlNode<tXmlCaseDefinition>
{
public:
tXmlCaseDefinition();
tXmlCaseDefinition(const pugi::xml_node& parent);
~tXmlCaseDefinition();
protected:
int n_shapes;
}
;
(I guess it is due to the specialization that I do not need to construct this class as a template class.)
Its not-default constructor is implemented as follows:
nXml::tXmlPart::tXmlPart(
const pugi::xml_node& parent,
const int npos) : tXmlNode(parent, npos), this_id(""), this_type(""), description("")
{
}
;
As you can see I did not delegate to the parent constructor by using tXmlNode<tXmlCaseDefinition>(parent,npos) but simply tXmlNode(parent,npos). I didn't pay attention to that and it works for some mysterious reason. I simply cannot understand why. Can somebody explain?
Also do I need to use tXmlNode<Part>(part) or can I use tXmlNode(part) instead for classes not derived from the specialized parent class or is this only possible when I have a spezialized parent?
Thank you very much!
Within the definition of a template class (more formally, the "current instantiation"), there is something called an injected-class-name, which is simply the name of the template sans arguments. For example:
template<class T>
struct Foo
{
Foo* ptr; // refers to Foo<T>
};
When you derive from a templated class, the base class' injected-class-name is inherited. Therefore you can also refer to the base class sans template arguments (assuming the name is accessible; some ancestor didn't privately inherit from it):
template<class T>
struct Base
{
};
struct Derived : Base<int>
{
Base* ptr; // refers to Base<int>
};
cppreference does a decent job of summarizing all the standardese here (Refer to [temp.local], [basic.lookup], and [basic.scope.class])
This is kind of a two-part question, but I believe they're very closely related.
Question 1:
I've read on other questions that there are ways to enforce a class in having certain static functions, like such:
class Type{
virtual void staticVirtual() = 0;
};
template<typename T>
class StaticContract{
void staticVirtual(){
T::foo();
}
};
If I made a class that inherited from this contract:
class Example : public StaticContract<Example>{
...
};
Then Example would have to implement a static function foo().
The problem I'm having is if I make a templated class that inherits from the contract:
template <Typename T>
class mTemplateClass :
public StaticContract<mTemplateClass<T>>{
...
}
I don't get any errors for not implementing foo().
How can I enforce a template to have certain static functions that I can call, or is that even possible?
Question 2:
Considering the above question, each StaticContract contains a static instance of a Registration that is instantiated with the type passed, (StaticContract<typename T> and will have a Registration<T>):
template <typename T>
class Registration :
public Registrants
{
public:
Registration() {
vectorOfFunctions->push_back(&T::foo);
}
};
When the class inheriting from StaticContract is not a template, this works fine, but when its a template, it'll never push back an instance of its function, not to mention it doesn't even enforce its implementation.
How can I push back this function from the most derived class?
In the sample:
#include <iostream>
using namespace std;
class B
{
public:
virtual void pvf() = 0;
};
template <class T>
class D : public B
{
public:
D(){}
virtual void pvf() {}
private:
string data;
};
template <>
class D<bool> : public B
{
public:
D();
virtual void pvf(){ cout << "bool type" << endl; }
};
int main()
{
D<int> d1;
D<bool> d2;
}
I get the following error:
test.cpp:(.text+0x1c): undefined reference to `D<bool>::D()'
Note that the reason I don't just specialize the D() by itself is I want to eliminate the need for string D<T>::data in the D<bool> case.
Why do I need to re-implement D() in D<bool>? Seems like there should be a way for me to tell the compiler to use the version from D<T>.
Is there any way to do a simple specialization like this without having to re-implement methods?
Each specialisation of a class template gives a different class - they do not share any members with each other. Since you've explicitly specialised the entire class, you don't get any of the members from the template, and must implement them all.
You can explicitly specialise individual members, rather than the entire class:
template <> void D<bool>::pvf(){ cout << "bool type" << endl; }
Then D<bool> will still contain all the members of the class template that you haven't explicitly specialised, including the default constructor.
No, there is not.
Specialization is behaving very differently than inheritence. It has no connection to the generic template version.
When you use/instantiate a template, the compiler will create a new type name, and then look for how this type is defined. When it finds a specialization, then it takes that as the definition for the new type. When it does not, it takes the generic template and instantiates it.
Therefore they have no connection, and you are just writing an entirely new class, just with a special name for the compiler to find in case of someone using/instantiating the template to find it under that name.
The problem is your erroneous assumption that there is anything common between D<A> and D<B>. Template instances are types, and two different instances are two different types, end of story. It only so happens that instances of the same template have formally similar code, but with specialization you can define any type you like. In short, every type that you define explicitly is entirely independent, and there is no commonality across specialized template instances, even if they happen to have the same name.
For example:
template <typename T> struct Foo
{
T & r;
const T t;
void gobble(const T &);
Foo(T *);
};
template <> struct Foo<int>
{
std::vector<char> data;
int gobble() const;
Foo(bool, int, Foo<char> &);
};
The types Foo<char> and Foo<int> have nothing to do with one another, and there is no reason why any part of one should have any use inside the other.
If you want to factor out common features, use private inheritance:
template <typename> struct D : private DImpl { /* ... */ }
You need to reimplement it because D<T> and D<bool> are totally unrelated classes (they just happen to "share the name"). That's just how templates work.
If you want the classes to share construction code, just put that code inside B::B (i.e. the same thing you do every time you want to reuse code in different branches of the same hierarchy: move the code up and let inheritance handle the rest).
Consider that D<T>::D() will be responsible for default-constructing string data, and that D<bool> doesn't have any such member. Clearly there is no way to use the same emitted code in each case.
However, if your default constructor doesn't do anything (in either version here), just omit it and allow the compiler to do the work.
I am using code::blocks, with, I believe gcc. Given the example code (this is pseudo code and may not replicate the problem):
//Assume this is in a separate header file to B
class TestA
{
protected:
int A;
public:
void Function1(){A = 0;}
};
class TestB : public TestA
{
public:
void CallFunction(){ A = 10; Function1();}//
};
I would get similar compile errors, like:
Error: 'A' not declared in this scope.
Error: Function1() not declared in this scope.
I was under the impression that all base variables and functions were inherited to the subclass. Given the base class has a lot of functions and variables, I don't want to use the 'using' keyword as I'd have to declare it for every function and variable (to my knowledge).
Is there any way to make it so TestB explicitly or actually includes the stuff it's inheriting?
Relevant snippets below
Okay. It's not possible to include example code as it's in project, but I will quote the key snippets:
C:\Users\user\Desktop\Projects\RND2\TemplateListAdv.h|30|error: 'Size' was not declared in this scope|
The line this is on is:
if(!Array.SetToSize(Size))
The class it's in is:
template<typename TemplateItem>
class TemplateListAdv : public TemplateList<TemplateItem>
And the incriminating line from TemplateList is:
SIZE_TYPE Size; //SIZE_TYPE is unsigned long.
//SIZE_TYPE is available in all files as unsigned long.
Files go:
TemplateList.h->TemplateBasics.h->TemplateListAdv.h
No missing files from what I can see.
I will tack in, the 'using' keyword resolves it individually, but this has been bugging me as I thought inheritance was automatic.
Compiler data as requested:
"Release 10.05 rev 6283 (2010-05-27 09:09:13) gcc 4.4.1 Windows/unicode - 32 bit"
So it looks like you are getting error wite template classes inheritance, isn't it? They are a big difference comparing to non-template ones. Assuming you have code like this:
template <class T>
class TestA
{
protected:
int A;
public:
void Function1(){A = 0;}
};
template <class T>
class TestB : public TestA<T>
{
public:
void CallFunction(){ A = 10; Function1();}//
};
The issue is caused by two-phase name lookup. All members of the base TestA class are dependent names, i.e. they depend on the template argument T. This is so because you can have template specialization for TestA with totally different members, e.g.:
template <class T>
class TestA
{
protected:
int A;
public:
void Function1(){A = 0;}
};
template <class T>
class TestB : public TestA<T>
{
public:
void CallFunction(){ A = 10; Function1();}//
};
template <>
class TestA<int>
{
};
Now, there is no A and Function1 members in the TestA, so they would be unaccessible in TestB as well. In order to let compiler know that these members are indeed depende on the template argument you should write TestB like this:
template <class T>
class TestB : public TestA<T>
{
public:
void CallFunction(){ this->A = 10; this->Function1();}//
};
This way you make compiler resolve names only during template instantiation time instead of template declaration time and it will known about base class members.
One thing to add is that there is no such issue with VC compiler, it doesn't try to parse templates until instantiation and thus don't support two-phase name lookup.
The problem that you're having about accessing base class stuff in a class template, is a FAQ item.
Rather then quoting the whole FAQ item here, I just link to it: that's your answer.
The code that you presented to illustrate the problem was unrelated, sorry. It is always a good idea to give an actual example rather than an example of what one thinks might be the problem.
Cheers & hth.,
The problem is that you are using templates, and the base class is a 'dependent name'. That is, the template base class could be specialized and not have the Size member, the compiler just doesn't know when it compiles your class, because the Size reference is not in a dependent context.
In your particular case the easiest solution is to refer to the inherited members using this:
if(!Array.SetToSize(this->Size))
And since this is a dependent name, it should work
Are you sure that :
Size is a protected or public attribute of TemplateList ?
you're not calling if(!Array.SetToSize(Size)) from a static method ?
The question is really bad, and you might want to improve on that. Anyway, my crystal ball tells me that Size is defined in a base template, and that because the identifier Size is not dependent lookup is not going into the base template and the compiler not seeing it. Add a this-> before Size and you should be set.
When interpreting a template member function, the compiler must (following the standard) decide for each symbol if it is dependent on the template parameter. If it is dependent on it, then it'll only be resolved when the template is instantiated. However, he must resolve it at this moment.
In your case, the compiler think that A and Function1 don't depend on the template parameter and should thus be resolvable just after the parse. You just have to make it depend on the template parameter by using this->A and this->Function1
So, you should have something like that.
template < typename T >
class Base
{
protected:
int A;
public:
void Function1() { A = 0; }
};
template < typename T >
class Derived : public Base< T >
{
public:
void CallFunction1() {
this->A = 10;
this->Function1();
}
};
In C++ I'm trying to make a simple state machine for a game, based on classes.
stateMan.setState<mainMenuState>();
I have a class with the declaration as:
class stateManager
{
...
template <class T>
void setState(void);
}
And the test code as:
template <class T>
void stateManager::setState<T>(void)
{
T* blah = new T;
delete blah;
}
And obviously this doesn't work since function template partial specialization ‘setState<T>’ is not allowed.
Would there be a better way to do this besides doing it non-OO?
The definition of the member function template should be this:
template <class T>
void stateManager::setState(void)
{
//...
}
That is, it should be simply setState instead of setState<T>. The latter syntax is used in function template specialization. Since T is a type parameter, the specialization would be considered as function partial template specialization which is not allowed.
Hard to say without the details, but you could do a base State class, and the different states inherit from it.
If you still want to use classes for this, you can see an interesting
example using boost.mpl.
Another option that avoids templates would be to define a pure virtual base class for your game states, and then pass references to different game-states to your function. For instance,
//pure virtual base class that will define the state interfaces
class base_state { /*...*/ };
//a derived state class
class mainMenuState : public base_state { /*...*/ };
class stateManager
{
//...
//you can pass any derived base_state to this function
void setState(base_state* state);
};