initializing mutable class attributes

Andrew Dalke adalke at mindspring.com
Fri Sep 3 11:01:32 CEST 2004


Alex:
> #include "Base.h"
> 
> int foo = 23;
> class Derived: public Base {
>     public:
>         Derived() { foo = 45; }
> };
> 
> Is this code correct?  Sure, it compiles and runs perfectly using Base
> version 12.3.  Then Base comes out with version 12.4 and this does not
> compile any more.  Why?  Because the new version of Base has added a
> private member named foo.

My C++ skills are rusty and old.  I had to experiment
with this to understand what was going on.  I had thought
that private: kept the above from happening.  Now I know
better.

I was wondering though about the justification of
"is this code correct" using "compiles and runs perfectly"
under a given circumstance.  That justification has
been applied to many incorrect pieces of code, including

#define SQUARE(x) ((x)*(x))

only to be proven wrong in the real world.  Part
of learning the language is learning about these
gotchas and acquiring the skills needed to do it
correctly.


The problem in your example is that variable lookup
occurs first in class then in static scopes.  I can
tell the compiler to only use static scope, as in

          Derived() { ::foo = 45; }

Based on my creaky memories, this shouldn't have
the same problems.  Does it have others?  And is
this this proper and accepted solution, meaning
that I should always write an explicit static
scope when I want to ensure I don't accidently
conflict with future changes to the base class?

				Andrew
				dalke at dalkescientific.com

P.S.
   Congratulations to the both of you!


P.P.S.

Is the modern implementation of that DOUBLE macro
something like

inline template<T>
T& DOUBLE(const T& x) {
   return T*T;
}

?  I don't think so since it doesn't do coercion
the same way.  Consider
   float f = .... ;
   double x = SQUARE(f);

The f*f gets promoted to double.  The macro version
assigns the double to a double so keeps the precision.
OTOH, the template version narrows the double to
a float (for the return value) then widens that
float back to a double, hence loosing precision in
the process.



More information about the Python-list mailing list