Re: How many bytes per Italian character?
"Doug Harrison [MVP]" <dsh@mvps.org> wrote in message
news:3vkk13lr8lis372qtet1o7ldqu2cds09nb@4ax.com...
You clipped the first part of my message, where I explained I'm not
interested in calling virtual functions from ctors and dtors. Let me
restore it, because the example I presented draws from it:
It's considered good practice not to call virtual functions from ctors
and
dtors. It doesn't really work quite right in any language, and it's even
worse in languages like Java and C#, which call the methods on
incompletely
constructed objects. Enabling one to do that is not the reason to provide
a
body for pure virtual functions. You provide a body for a pure virtual
function for the same reason you provide a body for a regular virtual
function.
A couple of points:
1. I would not describe a "good practice" and then motivate the existence
of something by doing its opposite, which is apparently how you
interpreted
my message.
2. I would not say, "Enabling one to do that is not the reason to provide
a
body for pure virtual functions," and then motivate providing a body by
presenting an example that illustrates what I just said is "not the
reason"
to do it.
3. When I said, "You provide a body for a pure virtual function for the
same reason you provide a body for a regular virtual function," and
presented an example immediately afterwards, it's a pretty safe bet that
my
example would illustrate what I meant by that.
What example was that? You only said
Offhand, the only time I
can recall doing this is when I had a group of functions that together
constituted an interface for saving and restoring state, and the base
class
had a tiny bit of state of its own, and I knew that all derived classes
would implement their own state. It would have been a mistake for any of
the derived classes to fail to override any member of this interface, so
it
made sense to make the virtual functions pure in the base. It made sense
to
give them bodies so that the derived classes could call up to them,
allowing the base to save its state.
which I thought I summarized by my code:
class CBase
{
public:
CBase()
{
InitBaseState(); // only visible to CBase
}
virtual void InitState() = 0; // derived classes must override,
no body defined!
private:
void InitBaseState(); // not virtual since it's only called from
base ctor
};
Here, both your goals are met without confusion: The base state is
initialized in ctor, and the derived classes clearly must override
InitState().
Initializing in the ctor using these functions was not one of "my goals".
But I guess not. As an aside, I note you like to give lots of words to the
problem; in fact, lots of words to describe even what you did NOT say, and I
rather like illustrative examples, so perhaps that's why we're not
connecting.
From the perspective of what I was actually talking about in my last
message, at the very least, your InitBaseState needs to be protected, so
that the derived classes can call up to it. With either approach, you need
to document that derived classes need to call the base class versions.
Your
approach requires more work, because you have to define the parallel set
of
non-virtual functions. I don't see any benefit to doing it that way.
OK, now I see where you're headed with this. The derived class needs to
override the InitState() function so it needs to be pure virtual. And it
needs to call the base class's InitState() function somewhere, either in its
implementation of InitState() or somewhere else, that's why it must not be
private. (But pure virtual functions do not force the derived
implementation to call the base's implementation, I don't think.)
So the real problem is that C++ jams two conflicting functionalities into
pure virtual functions. 1) Forcing derived classes to implement it; 2)
Providing a convenient place to implement base functionality for access by
both the base class and derived class.
These are somewhat contrary goals. The common sense usage of pure virtual
functions is to make it pure if the base class has no idea how to implement
the functionality, and that must be provided by the derived classes. If the
base class does have some idea of it, and therefore needs to implement the
virtual function, then don't make it pure. The derived classes have the
opportunity to supplement/replace the functionality by overriding the
virtual function or not, and if they do override, whether or not to call the
base class. It's presumptuous of the base class to assume the derived
classes will be implemented in such a way that they are forced to override
in this case.
-- David