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
   继承关系:
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
   // ~K
   J的析构没有被调用。
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



版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2013-03-06 17:40  J.Way.C  阅读(133)  评论(0编辑  收藏  举报