wrote:
> Thomas Tutone wrote:
> > wrote:
> > > I have an ABC with a protected member that is a reference to an object
> > > of an ABC type:
> > >
> > > class ABC
> > > {
> > > public:
> > > virtual ~ABC() = 0;
> >
> > your destructor should be protected, not public.
>
> Why is that? I can understand the constructor being protected, but not
> the destructor. Won't this mean that delete won't be able to call the
> destructors of inherited classes through the ABC interface?
Perhaps you are missing the point. ABC's destructor will never be
called directly - because the destructor is virtual, it will be the
destructor of the derived class that will be called, which will in turn
call the base destructor. The derived destructor has access to the
protected functions of its parent.
> > > protected:
> >
> >
> > your data member should be private, not protected.
> >
> > > AnotherABC& _member;
> > > }
>
> Why? Must I use access methods in my derived classes when one of the
> main points of the ABC is to provide a generalized declaration for my
> data members in the class hierarchy?
Typically, yes.
> Is it inadvisable to have
> protected data at all?
Typically yes. To quote Stroustrup: "declaring data members protected
is usually a design error." The C++ Programming Language (3rd ed.)
sec. 15.3.1.1
There are exceptions, but that's the usual rule. If your accessor is
inline, there is typically no overhead to using the accessor.
>
> >
> >
> > > The idea is that my concrete classes will derive from ABC and set
> > > _member in their initialization lists to the specific type of
> > > AnotherABC that the particular class needs.
> >
> > Can't do that. Instead, ABC needs a (protected) constructor that sets
> > member, and the derived class can call that constructor.
> >
> > > However, this can't be done
> > > as the constructors of the derived classes complain about there being
> > > no default constructor for ABC.
> >
> > It won't if you follow the above advice.
> >
> > > Should I simply replace the reference with a const pointer, or should I
> > > rethink this and save myself from a potentially nasty design flaw? Is
> > > there a design pattern I could use here?
> >
> > I've given you code below:
> >
> > class Other;
> >
> > class Base {
> > Other& other_; // this is private
> > protected:
> > virtual ~Base() = 0;
> > Base(Other& o) : other_(o) {}
You are correct - you need an accessor here. E.g.:
void doAction() { other.doAction(); }
or
const Other& other() const { return other_; }
or whatever... It's not clear (to me, anyway) what you are trying to
do.
> > };
> >
> > Base::~Base() {}
> >
> > class Derived : public Base {
> > public:
> > Derived(Other& o) : Base(o) {}
> > };
> >
> Thanks for your help, Tom. I hope my questions don't seem too stupid.
You're welcome, and they're not stupid. You might consider picking up
a copy of Effective C++ (3d ed.), which includes a lot of good advice.
Best regards,
Tom