By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,906 Members | 4,608 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,906 IT Pros & Developers. It's quick & easy.

Protected members

P: n/a
Why doesn't this work in g++?

class Base {
public:
Base() {}
~Base() {}
protected:
int foo;
}

class Derived : public Base {
public:
Derived(Base other) { foo = other.foo } // error : foo is protected
in this context
Derived() : foo(1) {} // error : no field foo in Base
Derived() { foo = 1; } // this works (obviously)
~Derived() {}
}

Is there any way to get around this?

Thanks,
Boaz

Aug 2 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
ba****@gmail.com wrote:
Why doesn't this work in g++?

class Base {
public:
Base() {}
~Base() {}
protected:
int foo;
}

class Derived : public Base {
public:
Derived(Base other) { foo = other.foo } // error : foo is protected
in this context
You cannot access protected members of other objects than this.
Derived() : foo(1) {} // error : no field foo in Base
Derived cannot initialize foo because Base already did: Base owns it.
Derived() { foo = 1; } // this works (obviously)
~Derived() {}
}

Is there any way to get around this?


1) use member functions
2) make Base initialize foo, pass an argument if necessary
Jonathan

Aug 2 '05 #2

P: n/a
<ba****@gmail.com> wrote in message
news:11**********************@g49g2000cwa.googlegr oups.com
Why doesn't this work in g++?

class Base {
public:
Base() {}
~Base() {}
protected:
int foo;
}

class Derived : public Base {
public:
Derived(Base other) { foo = other.foo } // error : foo is protected
in this context
Protected members are accessible to Derived only when part of a Derived
object's base. They are not accessible when part of a free standing Base
object or a Base component of some other type of object.

You can get access with a proper copy constructor:

Derived(const Derived & other) { foo = other.foo }
Derived() : foo(1) {} // error : no field foo in Base
An initialisation list of a derived class can only include

1. calls to base class constructors
2. initialisation of a class's own data members.

Direct initialisation of base class data members is not allowed. You should
define a constructor for the base class. If it is a default constructor
(i.e., has no arguments), then it will be called automatically. Otherwise,
you need to call it explicitly in the initialisation list.
Derived() { foo = 1; } // this works (obviously)
~Derived() {}
}

Is there any way to get around this?

Thanks,
Boaz

--
John Carson
Aug 2 '05 #3

P: n/a
* ba****@gmail.com:
Why doesn't this work in g++?

class Base {
public:
Base() {}
~Base() {}
protected:
int foo;
}

class Derived : public Base {
public:
Derived(Base other) { foo = other.foo } // error : foo is protected
in this context
Derived() : foo(1) {} // error : no field foo in Base
Derived() { foo = 1; } // this works (obviously)
~Derived() {}
}
Because the C++ language, not the g++ compiler, is defined that way.

To ease the explanation of why the language is defined that way, I'll first
improve the constructor declaration:

Derived( Base const& other ) { foo = other.foo; }

which is still not valid, but at least has pass-by-reference and the
required semicolon.

Now consider that 'other' may be of 'Base'-derived class 'Sensitive', where
the 'foo' member is always assumed to specify the size of a buffer. If
'Derived' could change 'foo' at will it could invalidate that extra
assumption in 'Sensitive', which 'Sensitive' otherwise is free to make based
on knowing that 'Base' doesn't meddle. It's not a very strong argument, but
it's basically the reason why C++ 'protected' only grants you access to that
member in objects of the class of the current object, or of classes derived
from that class; the relevant paragraph in the standard is 11.5/1.

Is there any way to get around this?


Provide a protected 'Base' constructor that takes a value for 'foo' as
argument, and make 'foo' private in 'Base'. Or, better, redesign.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Aug 2 '05 #4

P: n/a
* Jonathan Mcdougall:

You cannot access protected members of other objects than this.


class Derived;

class Base
{
protected:
int foo;
public:
void hm( Derived const& );
};

class Derived: public Base {};

void Base::hm( Derived const& other )
{
foo = other.foo;
}

int main() { Derived o; o.hm( o ); }

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Aug 2 '05 #5

P: n/a
Thanks for the answers! I figured that this was standard, but I just
wanted to know why. I see why this could be a problem in the
"Sensitive" case. However, I still have an issue, since I am writing a
program in which my base class needs to set itself up using an instance
of the derived class. I could provide accessors, but I feel like I'm
breaking encapsulation just for a derived class. I could also provide
some type of (protected) constructor in the base class, but I think
that the derived class's constructor really doesn't belong there.

This seems to me like a "feature" that makes inheritance work
inconsistently . . .

--Boaz

Aug 2 '05 #6

P: n/a
Then again, I guess I don't really care if there's a read-only property
visible . . .

Aug 2 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.