Static Method in base class accessing protected constructor of derived clas

S

softwaredoug

Here is some test code I've been attempting to compile (Visual Studio
2003)

test.h:

class Base
{
protected:
Base() {}
public:
template <class T>
static T* GetInstance() {return new T;} /*ERROR HERE :( */
};


class Derived
{
protected:
Derived() {}
};

class SomeCode
{
static void SomeCodeForYa();

};

test.cpp:
#include "test.h"

void SomeCode::SomeCodeForYa()
{
Derived* T = Base::GetInstance<Derived>();
}

I consistently get a compiler error: "error C2248:
'Derived::Derived' : cannot access protected member declared in class
'Derived'"

This *seems* like it should be allowed so long as the template
parameter is a derived from base. Am I missing something here? Is this
legal C++?
 
S

softwaredoug

Here is some test code I've been attempting to compile (Visual Studio
2003)

test.h:

class Base
{
protected:
Base() {}
public:
template <class T>
static T* GetInstance() {return new T;} /*ERROR HERE :( */

};

class Derived
{
protected:
Derived() {}

};

class SomeCode
{
static void SomeCodeForYa();

};

test.cpp:
#include "test.h"

void SomeCode::SomeCodeForYa()
{
Derived* T = Base::GetInstance<Derived>();

}

I consistently get a compiler error: "error C2248:
'Derived::Derived' : cannot access protected member declared in class
'Derived'"

This *seems* like it should be allowed so long as the template
parameter is a derived from base. Am I missing something here? Is this
legal C++?

Note, I noticed I left off the : public Base. I get the same error
irregardless

New test.h with correction:
Test.h:
#include "stdafx.h"

class Base
{
protected:
Base() {}
public:
template <class T>
static T* GetInstance() { return new T;}
};


class Derived
{
protected:
Derived() {}
};


class SomeCode
{
static void SomeCodeForYa();

};
 
G

Guest

Here is some test code I've been attempting to compile (Visual Studio
2003)

test.h:

class Base
{
protected:
Base() {}
public:
template <class T>
static T* GetInstance() {return new T;} /*ERROR HERE :( */
};


class Derived
{
protected:
Derived() {}
};

class SomeCode
{
static void SomeCodeForYa();

};

test.cpp:
#include "test.h"

void SomeCode::SomeCodeForYa()
{
Derived* T = Base::GetInstance<Derived>();
}

I consistently get a compiler error: "error C2248:
'Derived::Derived' : cannot access protected member declared in class
'Derived'"

This *seems* like it should be allowed so long as the template
parameter is a derived from base. Am I missing something here? Is this
legal C++?

Base does not have access to any of the (non public) methods in Derived.
Since Derived's constructor is protected you can not create an instance
of Derived in a static member function of Base.

The other way around would work, if GetInstance() was a member of
Derived and returned a pointer to Base.
 
J

James Kanze

On 2007-10-22 23:47, (e-mail address removed) wrote:

[...]
The other way around would work, if GetInstance() was a member of
Derived and returned a pointer to Base.

Not if the constructor it wanted to use was protected.
Protected in Base only grants access in Derived to the Base
objects which are, and are known to be, actually Derived. Thus,
for example, the constructor of Derived can call a protected
constructor of Base on itself (in the initialization list),
because the object is a Derived. But for example:

class Base
{
protected:
void f() ;
} ;

class Derived : public Base
{
void g( Base* pb, Derived* pd ) ;
} ;

void
Derived::g(
Base* pb,
Derived* pd )
{
f() ; // legal: is this->f(), and this is
// known to point to a Derived.
pb->f() ; // illegal !!!
pd->f() ; // legal.
}
 
J

James Kanze

On 2007-10-22 23:47, (e-mail address removed) wrote:

[...]
The other way around would work, if GetInstance() was a member of
Derived and returned a pointer to Base.

Not if the constructor it wanted to use was protected.
Protected in Base only grants access in Derived to the Base
objects which are, and are known to be, actually Derived. Thus,
for example, the constructor of Derived can call a protected
constructor of Base on itself (in the initialization list),
because the object is a Derived. But for example:

class Base
{
protected:
void f() ;
} ;

class Derived : public Base
{
void g( Base* pb, Derived* pd ) ;
} ;

void
Derived::g(
Base* pb,
Derived* pd )
{
f() ; // legal: is this->f(), and this is
// known to point to a Derived.
pb->f() ; // illegal !!!
pd->f() ; // legal.
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top