473,651 Members | 2,793 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

template<class Child> class Parent with protected constructors

I have several classes that all keep track of static data. However,
the manner that they keep track of static data is identical, and so
I'm using the template<class Child> class Parent { ... }; idiom (don't
know the name of it, if there is one). The problem is that I don't
want any of my classes to have public constructors. They should be
created by a static member function.

This is what I want to do, save for the fact that this doesn't
compile:

template <class Child>
class Foo {
protected:
static Child * foo;
Foo() { }
public:
static Child * get() { if(foo==NULL) return foo=new Child(); return
foo; }
};

class Bar : public Foo<Bar> {
protected:
Bar() { }
};

class Baz : public Foo<Baz> {
protected:
Baz() { }
};

Bar * Foo<Bar>::foo = NULL;
Baz * Foo<Baz>::foo = NULL;

main() {
Bar & bar = Bar::get();
Baz & baz = Baz::get();
}

The definition of "get" is flagged as an error, because the
constructor is protected. I've tried many different things, but
nothing gives me what I want.

In my actual code, I'm keeping a static set of all the instances of
the class, but I produced this simpler snippet for the sake of
discussion.
Jul 22 '05 #1
4 2746
On 4 Mar 2004 09:45:19 -0800, gr*********@hot mail.com (Grey Plastic) wrote:
I have several classes that all keep track of static data. However,
the manner that they keep track of static data is identical, and so
I'm using the template<class Child> class Parent { ... }; idiom (don't
know the name of it, if there is one). The problem is that I don't
want any of my classes to have public constructors. They should be
created by a static member function.

This is what I want to do, save for the fact that this doesn't
compile:

template <class Child>
class Foo {
protected:
static Child * foo;
Foo() { }
public:
static Child * get() { if(foo==NULL) return foo=new Child(); return
foo; }
};

class Bar : public Foo<Bar> {
protected:
Bar() { }
};

class Baz : public Foo<Baz> {
protected:
Baz() { }
};

Bar * Foo<Bar>::foo = NULL;
Baz * Foo<Baz>::foo = NULL;

main() {
Bar & bar = Bar::get();
Baz & baz = Baz::get();
}

The definition of "get" is flagged as an error, because the
constructor is protected. I've tried many different things, but
nothing gives me what I want.
Here's a modified version (comments indicate additions).
Compiles with: Comeau, MSVC 7,7.1
NOT: gcc (sigh), Borland, MSVC 6

#include <iostream> // just for NULL, really
using namespace std;

template <class Child>
class Foo {
protected:
static Child * foo;
Foo() { }
public:
static Child * get() {
if(foo==NULL) return foo=new Child();
return foo; }
};

class Bar : public Foo<Bar> {
friend class Foo; // added this
protected:
Bar() { }
};

class Baz : public Foo<Baz> {
friend class Foo; // added this
protected:
Baz() { }
};

//template<class Bar>
template<> // added this
Bar * Foo<Bar>::foo = NULL;

//template<class Bar>
template<> // added this
Baz * Foo<Baz>::foo = NULL;

int main() { // returns int
Bar & bar = *Bar::get(); // added *
Baz & baz = *Baz::get(); // added *
return 0; // added this
}
HTH,
-leor

In my actual code, I'm keeping a static set of all the instances of
the class, but I produced this simpler snippet for the sake of
discussion.


Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #2
Leor Zolman wrote:
On 4 Mar 2004 09:45:19 -0800, gr*********@hot mail.com (Grey Plastic) wrote:
....

Here's a modified version (comments indicate additions).
Compiles with: Comeau, MSVC 7,7.1
NOT: gcc (sigh), Borland, MSVC 6

#include <iostream> // just for NULL, really
using namespace std;

template <class Child>
class Foo {
protected:
static Child * foo;
Foo() { }
public:
static Child * get() {
if(foo==NULL) return foo=new Child();
return foo; }
};

class Bar : public Foo<Bar> {
friend class Foo; // added this
I don't believe that this is valid C++ code anyway. There is no
class Foo as it is not a template.

This might be more correct:

friend class Foo<bar>;

If you want all Foo's to access Bar you can do this:

template <class Child> friend class Foo;

protected:
Bar() { }
};

class Baz : public Foo<Baz> {
friend class Foo; // added this
.... ditto ...
protected:
Baz() { }
};

//template<class Bar>
template<> // added this
Bar * Foo<Bar>::foo = NULL;
Bar * Foo<Bar>::foo = 0; // :-)

I remember a discussion on this group a while back about using NULL. I
think the conclusion was that NULL was worse than useless and that the
literal 0 was much easier to deal with. It was along the lines of
confusion with the C version (or historic) NULL which was (void *)0 and
the fact the C++ has different semantics with void *.

//template<class Bar>
template<> // added this
Baz * Foo<Baz>::foo = NULL;

int main() { // returns int
Bar & bar = *Bar::get(); // added *
Baz & baz = *Baz::get(); // added *
return 0; // added this
}


g

Jul 22 '05 #3
On 04 Mar 2004 14:46:57 EST, Gianni Mariani <gi*******@mari ani.ws> wrote:

class Bar : public Foo<Bar> {
friend class Foo; // added this


I don't believe that this is valid C++ code anyway. There is no
class Foo as it is not a template.

This might be more correct:

friend class Foo<bar>;


Your version has the advantage of compiling with just about everything
under the sun (even MSVC6, gasp). I'm not yet convinced mine was illegal,
though...

//template<class Bar>
template<> // added this
Bar * Foo<Bar>::foo = NULL;


Bar * Foo<Bar>::foo = 0; // :-)

I remember a discussion on this group a while back about using NULL. I
think the conclusion was that NULL was worse than useless and that the
literal 0 was much easier to deal with. It was along the lines of
confusion with the C version (or historic) NULL which was (void *)0 and
the fact the C++ has different semantics with void *.


No doubt; in fact, I ended up changing them all to 0 after I posted so that
I could un-#include the header file in order to get it to compile in strict
mode under certain platforms. I try to post modified code with the fewest
possible changes from the OP's code, though, that aren't critical to the
issue at hand...just to avoid confusion. Not sure it always has that
effect...
-leor

Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
Jul 22 '05 #4
gr*********@hot mail.com (Grey Plastic) wrote in message news:<1d******* *************** ****@posting.go ogle.com>...
I have several classes that all keep track of static data. However,
the manner that they keep track of static data is identical, and so
I'm using the template<class Child> class Parent { ... }; idiom (don't
know the name of it, if there is one). The problem is that I don't
want any of my classes to have public constructors. They should be
created by a static member function.

This is what I want to do, save for the fact that this doesn't
compile:

template <class Child>
class Foo {
protected:
static Child * foo;
Foo() { }
public:
static Child * get() { if(foo==NULL) return foo=new Child(); return
foo; }
};

class Bar : public Foo<Bar> {
protected:
Bar() { }
};

class Baz : public Foo<Baz> {
protected:
Baz() { }
};

Bar * Foo<Bar>::foo = NULL;
Baz * Foo<Baz>::foo = NULL;

main() {
Bar & bar = Bar::get();
Baz & baz = Baz::get();
}

The definition of "get" is flagged as an error, because the
constructor is protected. I've tried many different things, but
nothing gives me what I want.

In my actual code, I'm keeping a static set of all the instances of
the class, but I produced this simpler snippet for the sake of
discussion.


That idiom called "Singleton" . The remaining posts actually answered
all the questions, so I'm off..
Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
6103
by: Math Preregistration System | last post by:
I'm using a std::list as a container for some pointers to objects, for example list< C* > lst; I would like to sort them using two different criteria, say first by C.first and then by C.second. Is it possible to use template <class C> void list::sort( C fn ) and define two different fns, and use them something like
0
1524
by: Dan Trowbridge | last post by:
He everyone, I just getting started with .NET and I am having a porting problem. I get and error in code that lookes like this (really stripped down but you get the idea)... class dt { std::deque< class dt > dtdq; };
5
1780
by: tuko | last post by:
The following snipet gives a linker error. I don't get it... template<class T> class tran { public: public: private: }; template<class T> class matrix {
7
3473
by: Dan Trowbridge | last post by:
He everyone, I am just getting started with .NET and I am having a porting problem. I get and error in code that lookssomething like this (really stripped down but you get the idea)... class dt { std::deque< class dt > dtdq; };
4
2663
by: Simon | last post by:
Hi, I am trying to create a round kind of function, (to round float and double to int). In the H file I can do the following with not too much trouble... // #include <limits> #include <math.h>
4
5072
by: Gary li | last post by:
Hi, all I find "template template" class cann't been compiled in VC6 but can ok in Redhat9. I write a test program like as: template< template<class> class T> class A { }; int main() { return 0;
1
2112
by: Birthe Gebhardt | last post by:
Dear all, I could not find the way to handle 'not normal' list objects, for example using remove_if, find etc. Example : class Todo { public : .. int getNumber(){ return num_;}
4
2314
by: Grizlyk | last post by:
Hello. Why were base class "typedefs" hidden by template<and explicit usage of them does not work too? Try open only one of the lines in the example below //using Tparent::Tptr; //typedef Tparent::Tptr Tptr; Consider example:
10
3533
by: jason.cipriani | last post by:
Is there any difference between declaring a template parameter as a "typename" or a "class"? E.g. template <class TT f() { } template <typename TT g() { } Thanks, Jason
0
8802
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8697
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8465
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8579
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7297
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4144
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4283
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2699
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1909
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.