C++ struct构造函数

    下面看看一道关于C++中笔试题:

#include <stdio.h>

struct test
{
    test(int n){
        printf("test(%d)\n",n);
    }

    test(){
        printf("test()\n");
    }

    void Fun(){
        printf("Fun()\n");
    }

/* 测试函数
   void operator()(){
        printf("vfunc\n");
    }
   测试函数 */
};

int main()
{
    test a(1);
    a.Fun();

    test b();
    b.Fun();  //19行

    //test b;
    //b.Fun();
    //b();
    return 0;
}


   找出这个程序错误的一行?

   答案很简单就是第19行,往下看就知道为什么啦!

   结构是一种用关键字struct声明的自定义数据类型。与类相似,也可以包含构造函数,常数,字段,方法,属性,索引器,运算符和嵌套类型等,不过,结构是值类型。但是,C++的结构和类是有区别的:
1、结构的构造函数和类的构造函数不同。
  a.结构不能包含显式的无参数构造函数。结构成员讲自动初始化为它们的默认值。
  b.结构不能包含以下形式的初始值设定类:base(argument-list);
2、对于结构中的实例字段成员,不能在声明时赋值初始化。
3、声明了结构类型后,可以使用new运算符创建构造对象,也可以不使用new,如果不使用new,那么在初始化所有字段之前,字段将保持未赋值状态且对象不可用。
4、结构不支持继承,即一个结构不能从另一个结构或类继承,而且不能作为一个类的基类。但是,结构从基类OBJECT继承。结构也可以实现接口。

   从编译角度来思考下:

摘自csdn: http://blog.csdn.net/fuadam/archive/2008/08/04/2766616.aspx

   最近才知道struct和class的静态构造函数的触发规则是不同的,不像class在第一次使用类的时候触发静态构造函数。如果只访问struct实例的字段是不会触发静态构造函数调用的。通过测试发现当访问静态字段,struct本身的函数(静态和实例)和带参数的构造函数就会引起静态构造函数的执行。而调用默认构造和未覆写的基类虚函数是不会的。为什么呢?
   让我们先来看看class和struct在调用构造函数时的区别。class使用newobj指令而struct使用initobj指令来构造对象。newobj在堆上申请一块内存并调用相应的构造函数进行初始化,然后将对象地址返回给计算栈。initobj则是从本地变量表中载入已经分配出来的struct实例然后初始化struct的各字段。这个初始化过程是CLR内部执行的,而不像class编译器会给class添加一个默认构造函数(这就是为什么struct不能给字段添加默认值的原因。但在类中如果给字段添加了默认值编译器就会自动在构造函数中添加字段赋值操作)。如果给struct中定义了一个有参数的构造函数,那么系统就不会使用initobj指令,而是直接用call指令调用带参数的构造函数。
   我们最常见最常用的调用函数的指令是call和callvirt。对于静态函数使用call指令,对于class使用callvirt指令(不论class中的函数是不是虚的)。只有子类调用父类的函数的时候(避免递归调用)以及构造函数中(由编译器添加保证父类字段被初始化)使用call指令。而对于struct我们发现只要调用的函数是struct本身定义的都是使用call指令。call和callvirt指令的差别在于,call会把调用的函数当作静态函数看待,而不会关心调用当前函数时实例指针(this)是否为空。这就是struct调用函数时为什么都是call因为struct实例是不可能被置为null的。实际上class在调用非虚函数时实际上也是使用call的只是多做了一步验证——this是否为空,让我们来验证一下。

在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
struct 是一种用户自定义的数据类型,用于封装多个不同类型的数据成员。在 C++ 中,struct构造函数用于初始化 struct 的实例化对象。 struct构造函数与类的构造函数相似,用于在创建对象时对数据成员进行初始化。通过在 struct 中声明和定义构造函数,可以方便地初始化对象的数据成员,提高代码的可读性和重用性。 struct构造函数可以有以下特点: 1. 构造函数的函数名与 struct 的名称相同,并且没有返回类型(连 void 也没有)。 2. 构造函数可以有多个重载版本,根据参数的不同进行区分。 3. 构造函数可以有默认参数,使部分参数可以省略。 4. 构造函数可以在构造时执行一些初始化操作,例如给数据成员赋初值、打开文件、分配内存等。 使用 struct 构造函数可以在创建对象时,直接传入参数进行初始化,而无需通过额外的成员函数进行赋值操作。这样可以简化代码,并且保证了对象的初始化过程的一致性。 例如,定义一个 struct Person,其中包含了姓名和年龄两个数据成员。可以通过定义构造函数来初始化这两个成员: struct Person { string name; int age; Person(string n, int a) { name = n; age = a; } }; 通过定义了一个带有两个参数的构造函数,可以在创建 Person 对象时,直接传入参数进行初始化: Person p1("张三", 20); Person p2("李四", 25); 这样就可以通过 struct 构造函数来方便地初始化对象的数据成员。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值