Re: questions about virtual functions and abstract classes
On Jun 21, 2:44 pm, Jess <w...@hotmail.com> wrote:
On Jun 21, 2:39 am, James Kanze <james.ka...@gmail.com> wrote:
Sort of:-). You're writing the constructor, and it is up to you
to know how far along you are in construction, and what
functions will or will not work. Most of the time, most
programmers try to do all critical initialization in the
constructor initializer list, so that once in the body of the
constructor, they have an object with consistent state, on which
they can usually call most functions. (Note the frequent use of
"most" and "usually" in the above.
Thanks. :) I think in the constructor initializer list, we should
initialize the data members and probably call base class constructors.
What other "critical" initialization do we need to do there?
Basically, you want to be sure that the class is in a state that
you can call member functions on it. This means that all base
classes and data members have been initialized. It shouldn't
mean anything more; at any rate, you can't do more than that in
the initializer list.
Note that the constructors for all base class and data members
*will* be called, whether they appear in the initializer list or
not. It's only important to put them in the initializer list
when the default constructor doesn't do what you want. (For
built-in types, of course, the default constructor doesn't do
anything, which is never what you want, so you'll always want to
initialize members with built-in type in the initializer list.)
Note to that initialization of the base classes and members
follows a pre-defined order, independantly of the order you
specify initialization in the initializer list. The order is:
1. Virtual base classes (only in the most derived class), in
the order they appear in a depth first left to right
traversal of the inheritance tree.
2. Immediate base classes, left to right.
3. Members, left to right.
(In the above, left to right means in the order the declarations
appear in the source code.) Some compilers will warn if the
initializers in the initialization list aren't in the same
order.
Note that the compiler
will generate such calls to the same function in the base
class implicitly in constructors, the destructor, and in a
compiler generated assignment operator.
Do you mean if I have a derived class B, base class A, then in B's
constructor, the compiler generates A::A(), in B's destructor it
generates A::~A() etc?
Yes. It is, by definition, impossible to have an instance of A
without A's constructor having been called. Even if that
instance is only a base class subobject. Try my example above:
with the undefined behavior commented out, it prints:
Middle
Derived
I'm very surprised that you have to ask that. It's one of the
basics of C++, and should be covered by any book that explains
inheritance, no matter how simply.
The books I read did say that. I was just not sure which "same
function" you refered to, so I probably asked a dumb question. :)
Not at all. I probably should have been clearer, since "same
function" isn't really very explicit here. What I meant was
simply that in the constructor, the compiler will generate calls
to the constructor, and in the destructor, calls to the
destructor. (But of course, A's constructor isn't the same
function as B's constructor, especially if they're both
overloaded.)
--
James Kanze (GABI Software, from CAI) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34