> Recently, I switched from CW8 to 9 for Mac OS X programming. Then
> suddenly, I encountered several problems for my C++ object oriented
[quoted text clipped - 11 lines]
>
> Masa
> I'm not an expert on the standard and I haven't seen your code, but
> something obviously has changed from CW8 to CW9
If I remember correctly the layout of the object has changed.
If your code relies on that not changing you are in trouble.
> Our Windows guys had a problem w/class initialization lists in VC++6 if the
> variables in the list were not declared in the exact same order as in the
[quoted text clipped - 14 lines]
> // order is now b a c in init list: b might not be initialized.
> A::A() : b( 0 ), a( 0 ), c( 0 ) {}
It is a given that initializer lists should not be ordered differently than
the order they are in the class. One of the reasons is that you won't
get what you expect because they will get done in the order they
are in the class not in the initializer list.
In the provided example it will be fine, in the following example it won't:
class A
{
A() : b( a ), a( 1), c( 0 ) {};
};
For more on this please take a look at Effective C++ rule #13.
It describes it in more more lucid detail. :)
HTH
Woolie
masa - 24 May 2004 13:14 GMT
Thank you very much for the responses. I've been trying to narrow down
the element of the problem and to make an example, because my code is
too large to show as an example. It took me a long time, but finally I
grabbed the core part. It seems a little complicated. The problem is
not simply the arrangement of the members, but is the problem of the
boundary of a class structure and the problem only happens in a
certain hierarchical structure. In a hierarchy, if you have a virtual
function in the base class and derived classes are connected virtual
to it, destruction of the class boundary occurs at one of the
constructor processes in derived classes. It is hard to explain by the
word, so I will copy and past my example program. In this case, member
variables of the base class (A) are arranged from private member m to
public members x, y, and n in memory. In constructor of class C, the
private member m of class A is destroyed. If you select 68k memory
structure alignment, the next pointer x is also affected. It is easy
to take a look what's happening by the debugger. If you put dummy
(long value) before member m, the program runs without problem at
least.
Masa
/*
* Copyright © 1997-2003 Metrowerks Corporation. All Rights
Reserved.
*
* Questions and comments to:
* <mailto:support@metrowerks.com>
* <http://www.metrowerks.com/>
*/
#include <iostream.h>
#include <stdlib.h>
class A {
/*long dummy;*/ /* solution */
short m;
public:
short *x;
short *y;
short n;
A();
void printPrivate(void);
virtual void f(void) {} /* problem */
};
A::A()
{
x = (short *) malloc(10 * sizeof(short));
y = (short *) malloc(10 * sizeof(short));
m = 123;
n = 456;
short i;
for (i = 0; i < 10; i++)
x[i] = i;
}
void A::printPrivate(void)
{
cout << m << '\n';
}
class B : public virtual A {
public:
B();
};
B::B()
{
}
class C : public virtual B {
public:
C();
};
C::C()
{
}
class D : public virtual B {
public:
D();
};
D::D()
{
}
class E : public C, public D {
public:
E();
};
E::E()
{
}
int main()
{
using namespace std;
E *e = new E;
e->printPrivate();
cout << e->n << '\n';
short i;
for (i = 0; i < 10; i++)
cout << e->x[i] << '\n';
return 0;
}