c/c++ 中结构体的初始化与类的初始化的不同之处

在C++ 中类的初始化会调用构造函数,根据构造函数来初始化类的变量。如果某个变量没有初始化,则该变量的值是一个随机值。

结构体的初始化,是根据所给值来初始化的,如果结构中某个变量的没有赋值,那么该变量被赋值为0.

简单的例子:

Demo1:

#include<iostream>
using namespace std;

struct T
{
  int a,b;
  char szName[20];
};

int main()
{
 struct T t = {1};
 cout<<t.a<<endl<<t.b<<endl<<t.szName<<endl;
 return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

猜一下输出结果吧,很容易就是1,0 
那么类呢?

Demo2:

#include<iostream>
using namespace std;

class T
{
  public:
  T(){};
  ~T(){};
  int a,b;
  char szName[20];
};

int main()
{
 T t ;
 cout<<t.a<<endl<<t.b<<endl<<t.szName<<endl;
 return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

答案也能猜到吧!就是一堆乱码==. 
这些很简单,但当一个结构体里面含有类或者结构体呢,结果会怎么样呢? 
类的成员该是什么呢,是空还是乱码?

Demo3:

#include<iostream>
using namespace std;

class OldMan
{
public:
    OldMan(){};
    ~OldMan(){};
    char szName[10];
};

struct Man
{
  char szName[20] ;
};

void  test()
{
     struct s {int a ,b ;char nNum[10]; OldMan oldm; Man man;};
     s t={1};
     cout<<t.a<<endl<<t.b<<endl<<t.nNum<<endl
     <<t.oldm.szName<<endl<<t.man.szName<<endl;
};

int _tmain(int argc, _TCHAR* argv[])
{  
    test();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

输出是什么呢?能猜到吗?答案等会告诉你,你先猜吧。

如果类中含有结构体,而此时类的构造函数却又没有任何初始化的操作呢?答案又是什么样的?

Demo4:

#include<iostream>
using namespace std;

struct Beer
{
  int a,b;
  char szName[20];
};

class Man
{
public:
    Man(){};
    ~Man(){};
    char szName[20];
    Beer br;
};

int main()
{
 Man m;
 cout<<m.szName<<endl<<m.br.a<<endl<<m.br.b<<m.br.szName<<endl;
 return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

答案是什么。。。 
看下面,4个Demo运行的结果吧: 
Demo1: 
这里写图片描述 
Demo2: 
这里写图片描述 
Demo3: 
这里写图片描述 
Demo4: 
这里写图片描述

看来结构的初始化,本着结构体内得所有成员都初始化的原则,进本数据类型就是零,而结构体内类的成员就会调用它本身的构造函数来初始化。 
类的初始化很简单就是按照构造函数初始化,编译器没有添加任何构造函数之外的操作。

我说你就信?^_^ 不能哦,我们还是要事实来说话,所以分析一下汇编代码吧,看看编译器是不是按照以上原则来编译Demo的,这里就分析Demo3吧!因为他很具有代表性,其他你自己来! 
首先在test()处设置断点后,进入test()函数内部,查看汇编代码: 
这里写图片描述 
首先对于函数压栈的初始化我们就不看了, 
看区域1:这是对变量a,b,nNum的初始化过程可以看到直接进行赋值操作 
mov: * * 
而区域2中却是调用call指令: 
call OldMan::OldMan(01111087h) 
来初始化成员 oldm 
下面的 mov 是初始化 man的。ok了。编译器确实是按照上面说的原则做的,这些Demo我在两个编译器上做了实现与查看汇编,汇编的代码不一样,但原理一样的。 
看完你似乎懂了 
但不要忘记初始化结构体哦,要不就会这样: 
Demo5:

#include<iostream>
using namespace std;

struct T
{
  int a,b;
  char szName[20];
};

int main()
{
 struct T t ;
 cout<<t.a<<endl<<t.b<<endl<<t.szName<<endl;
 return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

结果就是乱码了: 
这里写图片描述

猜你喜欢

转载自blog.csdn.net/hmdong7/article/details/78944680
今日推荐