Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > template<class Child> class Parent with protected constructors

Reply
Thread Tools

template<class Child> class Parent with protected constructors

 
 
Grey Plastic
Guest
Posts: n/a
 
      03-04-2004
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.
 
Reply With Quote
 
 
 
 
Leor Zolman
Guest
Posts: n/a
 
      03-04-2004
On 4 Mar 2004 09:45:19 -0800, http://www.velocityreviews.com/forums/(E-Mail Removed) (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
(E-Mail Removed)
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
 
Reply With Quote
 
 
 
 
Gianni Mariani
Guest
Posts: n/a
 
      03-04-2004
Leor Zolman wrote:
> On 4 Mar 2004 09:45:19 -0800, (E-Mail Removed) (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

 
Reply With Quote
 
Leor Zolman
Guest
Posts: n/a
 
      03-04-2004
On 04 Mar 2004 14:46:57 EST, Gianni Mariani <(E-Mail Removed)> 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
(E-Mail Removed)
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
 
Reply With Quote
 
pw4getter
Guest
Posts: n/a
 
      03-05-2004
(E-Mail Removed) (Grey Plastic) wrote in message news:<(E-Mail Removed). 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..
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
If a class Child inherits from Parent, how to implementChild.some_method if Parent.some_method() returns Parent instance ? metal Python 8 10-30-2009 10:31 AM
Is the possible to have all the public constructors of the publicbase class as the constructors of a derived class? Peng Yu C++ 5 09-19-2008 10:19 AM
compiler synthesized constructors/copy constructors/assignment operators Jess C++ 5 06-07-2007 11:09 AM
Copy constructors, de/constructors and reference counts Jeremy Smith C++ 2 08-02-2006 11:25 PM
Constructors that call other Constructors Dave Rudolf C++ 12 02-06-2004 03:26 PM



Advertisments