zoukankan      html  css  js  c++  java
  • 【总结】C++与C#中的struct结构体

    C++结构体

    支持继承,甚至可以多继承,虚继承,多态,重载运算符,模板,定义友元函数,友元类等。

     
    C++ 结构体和类区别
    • 和C不一样,C++结构体可以有成员函数、构造函数、继承和多态,相比C增加了很多功能
    • 默认public,无论是继承还是修饰变量(本质区别),这点和class,C#都不同
    struct B : A。继承默认是public的,而class默认是private的
    • struct可以继承class,同样class也可以继承struct,那么默认的继承访问权限是看子类到底是用的struct还是class
    你可以将程序里所有的class全部替换成struct,它依旧可以很正常的运行
    • 关键字“struct”不能用于定义模板参数,而class可以
    • 结构体没有默认构造函数,所以没有定义构造函数时可以使用 ={ } 初始化列表赋值public变量
    • 思想: struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。
     
    结构体对象所占的空间大小
    字节对齐:每个成员前面的字节数(即成员地址)需要是自身大小的倍数 。即当前成员的偏移量(起始位置)必须是成员变量大小的整数倍,不是的话在后面填充字节。
    字节对齐的目的是让计算机快速读写,是一个以空间换取时间的方式。
     
    内存补齐:结构体大小必须是最大成员的倍数。不是的话还要填充。
    1. 32位机中,如果成员大于4字节则以4字节整数倍为基准对齐;64位机中则以8字节作为基数上限。
    2. 补齐是为了让这个结构体定义的数组变量时候,数组内部,也同样满足内存对齐的要求。
    #pragma pack(n) 表示默认以n字节对齐(上限),若某变量(如int)的字节大于n,则以n的倍数对齐,内存补齐同理
     
    例题1:
    sizeof (64位机)
    struct st_t {
        int status;
        short *pdata;
        char errstr[32];
    };
    注意64位机指针占8个字节,而且要补齐4个字节,所以4+8+32+4=48
     
    例题2:
    64位机上,一个结构体有三个成员,分别是char、int、short类型,三个成员位于结构体中不同位置时整个结构体的大小可能是哪些值?
    三个数据,一共6种排列:
    int 4B   char 1B   short 2B
    根据内存对齐原则:
    1. char int short   char1 + 空3 + int4 + short2 + 空2 = 12
    2. char short int   char1 + 空1 + short2 + int4 = 8
    3. int short char   int4 + short2 + char1 + 空1 = 8
    4. int char short   int4 + char1 + 空1 + short2 = 8
    5. short int char   short2 + 空2 + int4 + char1 + 空3 = 12
    6. short char int   short2 + char1 + 空1 + int4 = 8
     
     

    C#结构体

    与C++结构体区别
    默认访问权限为 private
    struct是值类型,其实例在栈上分配内存
    class是引用类型,其实例在堆上分配内存
     
    比如 int 是结构体int32的关键字,所以是值类型。 是从System.ValueType继承的,但是只有他们装箱(boxing)的引用类型是从这里继承的,他们的值类型不是从任何地方继承的,就是.net的内部类型。
    System.ValueType是从System.Object继承的。你用了struct关键字,就表明了System.ValueType的继承关系,无需指明。
     
    所有结构体都继承ValueType父类,结构体不能被其它类继承。
    结构体可以实现接口,却不能继承其他的class
    因为值类型不能继承类类型
     
    结构体定义
    关于C++中结构体的定义声明,我用一段代码来演示吧。
    
    
           // 类型别名:为现有类型创建别名
           typedef int in;
           // 这里是定义结构体的同时用typedef取了个叫Stu的别名
           typedef struct Student
           {
                  string name;
           }Stu;
           // 还可以用using声明别名
           using init = int;
           in i = 0;
           // 结构体对象的几种构造方式
           Stu s1{ "xx" };
           Student s2{ "ss" };          // 在C语言中你不能使用这种构造方式。。
           struct Student s3();  // 在C语言中,Stu视为struct Student
           init j = 0;
           // decltype可以获得对象或函数返回值的类型,从而进行一些操作。但是这不是反射,这是编译时获取的类型
           decltype(s1) type = s2;
    
    
    

    以上代码表明了C++和C中定义结构体变量的区别

    C语言通常用typedef或struct Student的方式定义

    C++中你可以用using别名,Student直接定义

    C#中,和类差不多

    共用体

    定义:union name { };
    共用体的作用就是不同的类型的变量共享同一个地址,好处是节省开销,缺点是同一时刻仅仅能存储一个成员。
     
    共用体的大小是所有成员中占内存最大的那个,初始化时只能有一个常量。
    • 共用体不能同时引用几个成员,他只能用上一次赋值过的那个成员,其他成员都被覆盖掉了
    • 共用体变量不能初始化
    • 共用体变量不能作为函数参数(指针可以)
    • 大小端模式(这个有兴趣可以了解)
     
    例题:
    下列代码的输出结果有可能是哪些
    #include<stdint.h>
    #include<stdio.h>
    union X
    {
        int32_t a;
        struct
        {
            int16_t b;
            int16_t c;
        };
    };
    int main(){
        X x;
        x.a=0x20150810;
        printf("%x,%x ",x.b,x.c);
        return 0;
    }
    答:2015,810 或 810,2015
     
    0x20150810 如果按照大端模式存储(和阅读习惯一致):从低地址到高地址:20 15 08 10
                                      输出从低地址到高地址:20 15 08 10
    如果按照小端模式存储:从低地址到高地址:10 08 15 20 
                                      输出从高地址到低地址:08 10 20 15
     
     
     
     
     
     
  • 相关阅读:
    【OpenCV入门指南】第一篇 安装OpenCV
    java.lang.Math中的基本方法
    padding与margin的差别
    怎样做到从程序猿到管理者的跳跃
    秒杀多线程第四篇 一个经典的多线程同步问题
    NETSH WINSOCK RESET这条命令的含义和作用?
    如何在windows系统自带命令查看硬件信息?
    centos6.5 无线网卡配置
    ctagst简单应用,将Vim改造:Ctags,Taglist,Cscope,OmniCppComplete,SuperTab,Winmanager,NERDTree,MiniBufExplorer,vimrc
    lsof 拥有更多的功能
  • 原文地址:https://www.cnblogs.com/sols/p/8807414.html
Copyright © 2011-2022 走看看