Re: problems with inheritance and protected attributes
Thanks for your suggestions, but that didn't do it for me. I however
do understand what was wrong with the code earlier (I had fixed it
without knowing how).
My real problem now is the one that was posted on the second e-mail,
sorry about the mess.
This project is a research project, and it involves dynamic
programming, so given the recursive nature of the project I wanted to
be able to transverse the list in a easier/faster way than going
through iterators (and avoiding some of the overhead std::list
causes).
The Base class represents a production planning period (of a
production line) and has its data set, a method for calculating the
total cost up to the current point, a method for adding periods to the
list and the list pointers. The Derived class, adds functionality to
the base class, it has a few other attributes and overrides the method
to calculate the total cost, but most of the functionality remains the
same.
As I said, I'm having trouble accessing the protected data of the base
class from within the overridden virtual method of the derived one.
Where I get the error already posted:
--- Compiler error
wwperiod.hpp: In member function 'virtual double
ZWPeriod::getMinimalCost()':
wwperiod.hpp:50: error: 'DATATABLE* WWPeriod::resTable' is protected
zwperiod.cpp:46: error: within this context
(and the same error for a lot of other attributes in the same
method).
--- Classes layout
class WWPeriod {
public:
virtual double getMinimalCost();
protected:
DATATABLE *resTable;
};
class ZWPeriod: public WWPeriod {
public:
virtual double getMinimalCost();
};
--- Line giving the presented error:
zwperiod.cpp:46: resTable[0].tempCost = prev->resTable[0].tempCost +
prev->holdCost;
---
I'm a reasonably good C programmer, but although I know C++ syntax,
I've never really had any serious projects in C++, so I'm
unexperienced.
Thank you for your reply, but my problem remains.
Any more suggestions for a n00b? :D
Lucas
PS: I am using STL on other parts of the project, I just wanted to
avoid it in that specific part.
On Sep 30, 3:23 am, "Alf P. Steinbach" <al...@start.no> wrote:
* Lucas Kanebley Tavares:
I'm working on a project with a layout similar to this:
class A {
protected:
A *next;
int i;
public:
void m(A *a);
};
class B: public A {
public:
void m(B *b);
}
where both A and B are linked lists, but each one of its own type, and
m is a method that manipulates A's 'next' attribute, for instance:
A::m(A *a) {
a->next = next;
i++;
}
as the behavior would be exactly the same for B, I did:
B::m(B *b) {
A::m(b);
}
But that gives me errors on compiling whenever method B::m, tries to
access a protected member of class A (for instance incrementing i).
It would be nice if you posted the actual offending code, but happily
this "problem" is not uncommon, so it is reasonable to assume you have
something like
B::m( B* b )
{
A::m( b );
next->i = 666;
}
That will cause the compiler to complain, because while B can access
protected A features on B objects, and on objects of classes publicly
derived from B, if it could do it could access protected A features on A
objects it could also access protected A features on Z-objects, where Z
is a class I have derived from A.
So in that case "protected" wouldn't be any protection: you could access
protected A features of my Z instances simply by deriving a class from A.
So C++ does not allow that.
I've tried declaring a new variable i to class B, but that just causes
both A::i and B::i to exist, and A increments A::i, while whenever
someone reads from B, it reads B::i. Which is obviously wrong.
Does anybody know how I can fix this?
Without knowing what you're trying to achieve it's difficult to fix it.
However, the above explains what the problem most likely is, and the fix
should involve not accessing protected A features on A objects down in
class B, but up in class A -- or else let those objects be B objects.
On the third hand, a little redesign is called for anyway, and it may be
that that also fixes your problem.
The reason a little redesign is called for: with the current design you
can't traverse the list and access the objects as B objects without
casting down from A* to B*.
And casting is ungood, because it's so easy to get wrong.
It seems that class A is a generic node-type, just a Linkable, and that
the idea is to add some data and behavior to each node down in class B,
serving as a full-blown Node.
Perhaps someone will suggest templatizing class A, but that will give
you code that's difficult to work with, in particular completely
indeciphericable kilometer-long error messages from the compiler.
So I suggest a simple forward declaration, and replacing the inheritance
with containment, where here class Data represents the stuff added in B:
class Data;
class Linkable
{
private:
Data* myData;
Linkable* myNext;
void linkIntoNextField( Linkable*& aNextField )
{
myNext = aNextField;
aNextField = this;
}
public:
Linkable( Data* data ): myData( data ), myNext( 0 ) {}
~Linkable() { delete myData; }
Data& data() { return *myData; }
Linkable* next() { return myNext; }
Linkable* insertAfter( Linkable* p )
{
linkIntoNextField( p->myNext );
return this;
}
Linkable* unlinkNext()
{
Linkable result = myNext;
if( myNext != 0 )
{
myNext = myNext->next();
}
return result;
}
};
class Data { ... };
class List { ... };
One interesting exercise is how many 'const' keywords it's possible to
sprinkle in this code. It should ideally be done.
Did anybody even understand what
I just asked?
Possibly.
I assumed that this is a school project where you're learning about
pointers etc., and where templating would just be added complication,
not a real-world project where you'd just use std::list.
I know I kinda lost me. :P
Any help would be greatly appreciated,
You're welcome.
--
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?