struct | class
1. 区别
默认的成员,继承修饰,struct为public,class为private。
2. 类和结构体的拷贝,赋值,在不涉及成员指针情况下可直接使用默认方式即可。
3. 构造函数调用时机:Struct s; 拷贝构造时机:Struct s = other; 赋值函数时机:Sturct s; s = other;
默认情况下不会相互调用,注意重载时勿要遗漏成员数据。
4. virtual 的应用
一、在继承方面:
B B B
| | / \
C D F G
\ / \ /
E H
①没有使用virtual ②使用了virtual
继承关系:
②的情况:F和G在虚拟继承之后结构上增加了一个指针的大小。H保留一份B的数据。
测试2:访问
测试3:多态
网上查到的资料说要对B的析构进行virtual修饰,修改之后的析构顺序为:
二、成员函数方面:一般指多态的实现
有个需要注意的方面是不要漏掉virtual对析构函数的修饰。
5. 内存对齐,这是编译器相关的
默认情况下不会相互调用,注意重载时勿要遗漏成员数据。
4. virtual 的应用
一、在继承方面:
B B B
| | / \
C D F G
\ / \ /
E H
①没有使用virtual ②使用了virtual
继承关系:
struct B { int ba; int bb; int bc; ~B() { printf("~B\n"); } }; struct C : B { int ca; ~C() { printf("~C\n"); } }; struct D : B { int da; ~D() { printf("~D\n"); } }; struct E : C, D { ~E() { printf("~E\n"); } }; struct F : virtual B { int fa; ~F() { printf("~F\n"); } }; struct G : virtual B { int ga; ~G() { printf("~G\n"); } }; struct H : F, G { ~H() { printf("~H\n"); } };测试1:数据结构
printf("B%d C%d D%d E%d\n", sizeof(B), sizeof(C), sizeof(D), sizeof(E)); printf("B%d F%d G%d H%d\n", sizeof(B), sizeof(F), sizeof(G), sizeof(H)); // out // B12 C16 D16 E32 // B12 F20 G20 H28①的情况:E会保存两份B的数据,一个来自C,一个来自D。
②的情况:F和G在虚拟继承之后结构上增加了一个指针的大小。H保留一份B的数据。
测试2:访问
E e1; /* e1.ba; error: request for member `ba' is ambiguous candidates are: int B::ba int B::ba */ H h1; h1.ba; // pass①的情况:E对B的成员访问会出现二义性。②没有二义性。
测试3:多态
//B* pb1 = new E; //error: `B' is an ambiguous base of `E' B* pb2 = new H; delete pb2; //*** glibc detected *** free(): invalid pointer: 0x08212018 ***① 似乎不行。②编译通过了,可是出了问题。
网上查到的资料说要对B的析构进行virtual修饰,修改之后的析构顺序为:
virtual ~B() // ~H // ~G // ~F // ~B // B16 C20 D20 E40 // B16 F24 G24 H32
二、成员函数方面:一般指多态的实现
有个需要注意的方面是不要漏掉virtual对析构函数的修饰。
struct I { ~I() { printf("~I\n"); } }; struct J : I { ~J() { printf("~J\n"); } }; struct K { virtual ~K() { printf("~K\n"); } }; struct L : K { ~L() { printf("~L\n"); } };测试1:析构
I* pi = new J; delete pi; K* pk = new L; delete pk; // out: // ~I // ~L // ~KJ的析构没有被调用。
5. 内存对齐,这是编译器相关的
struct N { int a; double b; float c; }; struct O { int a; float c; double b; }; printf("N%d O%d\n", sizeof(N), sizeof(O)); // out in linux gcc v3.4.4 // N16 O16 // out in windows vs2008 // N24 O16
版权声明:本文为博主原创文章,未经博主允许不得转载。