Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inheritance from template problem

16 views
Skip to first unread message

DSF

unread,
Jun 3, 2012, 2:03:21 PM6/3/12
to
Hello,

My inheritance problem is my uncle left me $10 million, but to get it
I have to spend the night in an isolated haunted house. My uncle
didn't like me. I think it's a plot to kill me! :o)


Seriously, when I compile the following code, I get the error: "B::i
is not accessible" on the line "f = Tptr->i". It compiles fine if "i"
is made public. I assume it has something to do with the declaration
of class "D".
I tried class "D : public A<B>, public B" with the same results.

Have I missed something simple?


template <class T> class A
{
protected:
T *Tptr;
};

class B
{
public:

protected:
int i;
};

class D : public A<B>
{
public:
void foo(void);
};

void D::foo(void)
{
int f;

f = Tptr->i;
}


DSF

Paavo Helde

unread,
Jun 3, 2012, 2:19:57 PM6/3/12
to
DSF <nota...@address.here> wrote in
news:va8ns7tbn6rce8sf7...@4ax.com:

> Hello,
>
> My inheritance problem is my uncle left me $10 million, but to get it
> I have to spend the night in an isolated haunted house. My uncle
> didn't like me. I think it's a plot to kill me! :o)
>
>
> Seriously, when I compile the following code, I get the error: "B::i
> is not accessible" on the line "f = Tptr->i". It compiles fine if "i"
> is made public. I assume it has something to do with the declaration
> of class "D".
> I tried class "D : public A<B>, public B" with the same results.
>
> Have I missed something simple?

I think yes. B::i is declared protected, meaning that only B or a class
derived from B can access it. There is no class derived from B. So...?

hth
Paavo

Paavo Helde

unread,
Jun 3, 2012, 2:22:54 PM6/3/12
to
Paavo Helde <myfir...@osa.pri.ee> wrote in
news:XnsA067D9022A4EEm...@216.196.109.131:

> DSF <nota...@address.here> wrote in
> news:va8ns7tbn6rce8sf7...@4ax.com:
>
>> Hello,
>>
>> My inheritance problem is my uncle left me $10 million, but to get it
>> I have to spend the night in an isolated haunted house. My uncle
>> didn't like me. I think it's a plot to kill me! :o)
>>
>>
>> Seriously, when I compile the following code, I get the error: "B::i
>> is not accessible" on the line "f = Tptr->i". It compiles fine if "i"
>> is made public. I assume it has something to do with the declaration
>> of class "D".
>> I tried class "D : public A<B>, public B" with the same results.
>>
>> Have I missed something simple?
>
> I think yes. B::i is declared protected, meaning that only B or a class
> derived from B can access it. There is no class derived from B. So...?

Oh, and even if you derive from B, the 'protected' keyword allows access
only via 'this', not via an arbitrary pointer like 'Tptr'. These are the
language rules.

Cheers
Paavo

Dombo

unread,
Jun 3, 2012, 2:27:09 PM6/3/12
to
Op 03-Jun-12 20:03, DSF schreef:
D is not derived from B hence it cannot access its protected members.
That B is used as a template parameter doesn't matter, it only means
that A has a member of type B, but doesn't create a inheritance relation
between B and D. Note that this is not template related problem; you
would get the same error with the following code:

class B
{
public:

protected:
int i;
};


class A
{
protected:
B *Tptr;
};


class D : public A

Balog Pal

unread,
Jun 3, 2012, 5:35:45 PM6/3/12
to
"DSF" <nota...@address.here>
> Seriously, when I compile the following code, I get the error: "B::i
> is not accessible" on the line "f = Tptr->i".

Yep. Just followinfg the rules.

i is protected member of class B. Why do you think it could be seen from
class D that is not derived from B?

> It compiles fine if "i" is made public.

Yep.

> I assume it has something to do with the declaration
> of class "D".
> I tried class "D : public A<B>, public B" with the same results.

If you add that you can write
f = i;

However Tptr->i is still not accessible as it is not part of the base class
you inherited but an unrelated instance.

If you really like you can hack around using a pointer-to-member, but I'd
suggest you to forget 'protected' entirely and make a clean public
interface.

Marcel Müller

unread,
Jun 3, 2012, 8:01:36 PM6/3/12
to
On 03.06.2012 20:22, Paavo Helde wrote:
> Paavo Helde<myfir...@osa.pri.ee> wrote in
> news:XnsA067D9022A4EEm...@216.196.109.131:
>
> Oh, and even if you derive from B, the 'protected' keyword allows access
> only via 'this', not via an arbitrary pointer like 'Tptr'. These are the
> language rules.

AFAIK that's not true.
You may access protected members in a base class also via pointers other
than this as long as they point to the same class type than this.


Marcel

DSF

unread,
Jun 4, 2012, 1:17:14 AM6/4/12
to
On Sun, 03 Jun 2012 14:03:21 -0400, DSF <nota...@address.here>
wrote:

Thanks to all who responded. I kind of suspected it related to the
pointer, since I did manage to get f to equal i without the pointer.

Once the fog from the template had lifted from my eyes, I Googled
around for "pointer to base class protected member c++" to learn why
this restriction exists. One of the hits was a forum that had the
scent of "copy of newsgroup" on it, so I went looking here. Mine is a
very oft-asked question!

Once I got my mind around the now obvious fact that the declaration
of an object is not necessarily the only instance of said object, the
reason was clear. Only allowing the this pointer (explicit or implied)
ensures only the current instance's base is accessed.

Are there any bad side effects to declaring D a friend of B (as
below)? In the real world code this example is based on, B and D have
a very close relationship. It also allows me to make "i" and other
data members of "B" private.

By the way, the forum postings with the newsgroup scent came from a
thread posted in this very group last March.

template <class T> class A
{
protected:
T *Tptr;
};

class B
{
friend class D;

Paavo Helde

unread,
Jun 4, 2012, 1:43:35 AM6/4/12
to
=?ISO-8859-15?Q?Marcel_M=FCller?= <news.5...@spamgourmet.com> wrote in
news:4fcbfae1$0$6567$9b4e...@newsspool3.arcor-online.net:
Yes, you are right:

"Except when forming a pointer to member, the access must be through a
pointer to, reference to, or object of the derived class itself (or any
class derived from that class)"

So, if OP wants to access some protected B::i via Tptr, then the Tptr
must point to a class that is the same than where the access takes place,
and of course this class also has to be derived from B. So, OP-s code
with modifications to get it to compile:

template <class T, class U> class A: public T
{
protected:
U *Tptr;
};

class B
{
public:

protected:
int i;
};

class D : public A<B, D>
0 new messages