VC++ Inheritance and protected members

J

John A. Byerly

Hi,

I have a couple of classes that are causing compile errors. I hope someone
can shed some light as to why.

class A
{
public:
A(X* pX) : m_pX(pX) {};

protected:
X* m_pX;
};

class SubA : public A
{
public:
SubA(A& a) : A(a.m_pX) {};
};

When I compile this, I get an error stating that I can't access protected
member A::m_pX.

Would someone be so kind as to 'splain this to me?

Thanks!

JAB
 
V

Victor Bazarov

John said:
I have a couple of classes that are causing compile errors. I hope someone
can shed some light as to why.

class A
{
public:
A(X* pX) : m_pX(pX) {};

protected:
X* m_pX;
};

class SubA : public A
{
public:
SubA(A& a) : A(a.m_pX) {};
};

When I compile this, I get an error stating that I can't access protected
member A::m_pX.

Would someone be so kind as to 'splain this to me?

You can't access protected members of a class different from the one from
which you try to access the protected members. You can rewrite your code
as

SubA(SubA& a) : A(a.m_pX) {}

_or_ give class A an accessor function that would return m_pX:

class A
{
...
X* get_pX() { return m_pX; }
...
};

SubA(A& a) : A(a.get_pX()) {}

And this problem has nothing to do with VC++ since it's the Standard C++
behaviour, often misunderstood.

Also, if you need to ask a VC++ question (which this one wasn't), you will
find microsoft.public.vc.language helpful. This particular question is
not compiler-specific, however.

V
 
J

John A. Byerly

Victor Bazarov said:
You can't access protected members of a class different from the one from
which you try to access the protected members.

Thanks!

Now I have a followup question :)

I am trying to make a storable version of a class. For instance,

class A
{
public:
A(double value) {};

protected:
A() : m_value(0.0) {};
double m_value;
};

I want to make a storable version of A, so I thought I would write

class StorableA
{
public:
StorableA() {};
Load(Storage& s) {???};
Store(Storage& s) {???};
};

I want to be able to pull values from storage and populate the object. That
should be easy: just create a StorableA and populate it. Okay, now, given
an instance of A, I want to be able to store it. One way of doing this
would be to create a sort of copy constructor for StorableA.

class StorableA
{
public:
StorableA() {};
StorableA(A a) : m_value(a.m_value) {};
Load(Storage& s);
Store(Storage& s);
};

StorableA::Store(Storage& s)
{
s.Store(m_value);
}

This won't work because I can't access protected members of A.

Am I out of luck?

JAB
 
J

Jeff Flinn

John A. Byerly wrote:

....
I am trying to make a storable version of a class. For instance,

class A
{
public:
A(double value) {};

protected:
A() : m_value(0.0) {};
double m_value;
};

I want to make a storable version of A, so I thought I would write

class StorableA
{
public:
StorableA() {};
Load(Storage& s) {???};
Store(Storage& s) {???};
};

If by "Storable" you mean serializable, then you might want to look at:

http://www.boost.org/libs/serialization/doc/index.html

Jeff Flinn
 
V

Victor Bazarov

John said:
[...]
I am trying to make a storable version of a class. For instance,

class A
{
public:
A(double value) {};

protected:
A() : m_value(0.0) {};
double m_value;
};

I want to make a storable version of A, so I thought I would write

class StorableA

Did you mean

class StorableA : public A

?
{
public:
StorableA() {};
Load(Storage& s) {???};
Store(Storage& s) {???};
};

I want to be able to pull values from storage and populate the object. That
should be easy: just create a StorableA and populate it. Okay, now, given
an instance of A, I want to be able to store it. One way of doing this
would be to create a sort of copy constructor for StorableA.

class StorableA
{
public:
StorableA() {};
StorableA(A a) : m_value(a.m_value) {};
Load(Storage& s);
Store(Storage& s);

A nit pick: get into habit of writing proper C++, even if you're writing
to illustrate something. Here two things are not right: extraneous
semicolons and functions that don't have return value types.
};

StorableA::Store(Storage& s)
{
s.Store(m_value);
}

This won't work because I can't access protected members of A.

That's not true (clearly you didn't try it, otherwise you'd already know
that it's not true). You are allowed access to any member of _your_own_
subobject. IOW, you are allowed to access this->[anyprotectedmember].
Am I out of luck?

Of course not.

V
 
J

John A. Byerly

Okay, as Victor pointed out, there were problems with the code snippet I
supplied. Here is an updated version:

class A
{
public:
A(double value) : m_value(value) {}

protected:
A() : m_value(0.0) {}
double m_value;
};

As I said, I want to be able to store an instance of A, so I was hoping to
do so by creating a subclass:

class Storage
{
public:
void Store(double value) {}
};

class SubA : public A
{
public:
SubA(A* pA) : m_pA(pA) {}
void Store(Storage& s);
void Load(Storage& s);

private:
A* m_pA;
};

void SubA::Store(Storage& s)
{
s.Store(m_pA->m_value);
}

Now, I said before:
To which Victor replied:
That's not true (clearly you didn't try it, otherwise you'd already know
that it's not true). You are allowed access to any member of _your_own_
subobject. IOW, you are allowed to access this->[anyprotectedmember].

What I meant was through the instance of A. The Store() function above
should make this more clear.
Of course not.

Please offer suggestions. I can't figure out how I can construct a fully
initialized instance of a subclass given an instance of the base class, so I
suspect my approach is flawed. But I haven't been able to come up with
another way to do this.

Thanks!

JAB
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

John said:
class A
{
public:
A(double value) : m_value(value) {}

protected:
A() : m_value(0.0) {}
double m_value;
};

As I said, I want to be able to store an instance of A, so I was hoping to
do so by creating a subclass:

class Storage
{
public:
void Store(double value) {}
};

class SubA : public A
{
public:
SubA(A* pA) : m_pA(pA) {}
void Store(Storage& s);
void Load(Storage& s);

private:
A* m_pA;
};

void SubA::Store(Storage& s)
{
s.Store(m_pA->m_value);
}
[snip]

Please offer suggestions. I can't figure out how I can construct a fully
initialized instance of a subclass given an instance of the base class, so
I suspect my approach is flawed. But I haven't been able to come up with

SubA (A * pA) : A (* pA) { }

And forget the m_pA member. The way you use does not initialize any A
instance, just stores a pointer to one.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Julián Albo said:
And forget the m_pA member. The way you use does not initialize any A
instance, just stores a pointer to one.

Correction, initializes one instance, but not whith the parameter passed.
 

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

Forum statistics

Threads
474,434
Messages
2,571,690
Members
48,796
Latest member
Greg L.

Latest Threads

Top