zoukankan      html  css  js  c++  java
  • c++类成员变量初始化相关问题

    对于内置变量的自动初始化

    代码1

    复制代码
     1 #include<stdio.h>
     2 #define CONST 100
     3 int *p1;
     4 int a[2];
     5 int b;
     6 static int c;
     7 main()
     8 {
     9     int d;
    10     static int e;
    11     int f[2];
    12     int *p2;
    13     printf("CONST=%d
    ",CONST);
    14     printf("a[0]=%d
    ",a[0]);
    15     //printf("*p1=%d
    ",*p1);
    16     printf("b=%d
    ",b);
    17     printf("c=%d
    ",c);
    18     printf("d=%d
    ",d);
    19     printf("e=%d
    ",e);
    20     printf("f[0]=%d
    ",f[0]);
    21     printf("*p2=%d
    ",*p2);
    22 }
    复制代码

    输出:

    CONST=100

    a[0]=0

    b=0

    c=0

    d=2514932

    e=0

    f[0]=1307813

    *p2=457819009

    数据区存放已初始化的全局变量,静态变量(包括全局和局部的),常量。

    未初始化数据区(uninitializeddata segment,BSS)存放全局未初始化的变量。BSS的数据在程序开始执行之前被初始化为0或NULL。BSS段的变量在目标文件中只占一个符号位,编译器并没有给变量分配空间,所谓的“初始化为0”是指要链接阶段才申请了空间,并随即初始化为0。而已初始化的全局变量要在占用目标文件的大小的。

    换句话说全局变量,静态变量(包括全局和局部的),常量未显式初始化被默认地初始化时0或NULL。

    如果试图打印*p1则会发生段错误,因为p1指向的是一个NULL地址。

    而局部的非静态变量未显式初始化时是一个随机的数,一般是个很大的数。

    对于类类型变量的自动初始化

    不论是在全局还是局部作用域,类类型变量都会调用“默认构造函数”进行初始化。

    所谓“默认构造函数”就是指空参数的构造函数。

    代码2

    复制代码
    class A{
    public:
        int value;
        A(){
            cout<<"Intitialize A"<<endl;
            value=3;
        }
    };
    
    A a1;
    
    int main(){
        A a2;
        cout<<a1.value<<endl;
        cout<<a2.value<<endl;
        return 0;
    }
    复制代码

    输出:

    Intitialize A
    Intitialize A
    3
    3

    如果类没有显式地定义任何构造函数,则编译器会自动为其生成空参数的构造函数,称为“合成默认构造函数”。“合成默认构造函数”初始化成员的规则有3条:

    1.对象在全局作用域或为静态局部对象时,则类的内置成员变量被初始化为0.

    2.对象在局部作用域定义时,则类的内置成员变量不被初始化为0。

    代码3

    复制代码
    class A{
    public:
        int value;
    };
    
    A a1;
    
    int main(){
        A a2;
        static A a3;
        cout<<a1.value<<endl;
        cout<<a2.value<<endl;
        cout<<a3.value<<endl;
        return 0;
    }
    复制代码

    输出:

    0
    2510836  (这里不为0,很多程序没有初始化,看到手动初始化是非常必须的。并不是无所谓。)
    0

    3.对于类类型成员按照其自身的(合成)默认构造函数进行初始化

    代码4

    复制代码
    class A{
    public:
        int value;
        A(){
            value=5;
        }
    };
    
    class B{
    public:
        int value;
        A a;
    };
    
    B b1;
    
    int main(){
        B b2;
        cout<<b1.value<<"	"<<b1.a.value<<endl;
        cout<<b2.value<<"	"<<b2.a.value<<endl;
        return 0;
    }
    复制代码

    输出:

    0     5
    134514784     5

    代码5

    复制代码
    class A{
    public:
        int value;
    };
    
    class B{
    public:
        int value;
        A a;
    };
    
    B b1;
    
    int main(){
        B b2;
        cout<<b1.value<<"	"<<b1.a.value<<endl;
        cout<<b2.value<<"	"<<b2.a.value<<endl;
        return 0;
    }
    复制代码

    输出:

    0   0
    134514736   -1081710584

    如果类显式提供了带参数的构造函数,则编译器不会再为其生成空参数的构造函数。这时候就不能用空参数来定义类类型变量。下面的代码是错误的:

    复制代码
    class A{
    public:
        int value;
        A (int i):value(i){}
    };
    
    int main(){
        A a;
        return 0;
    }

    转自:http://www.cnblogs.com/zhangchaoyang/articles/2671551.html

  • 相关阅读:
    COM+帐户权限注意事项
    [转]MVC和MVP的一些思考
    让VS智能感知Nhibernate的映射文件
    C#中使用Ftp一例
    [源码共享]以前用Remoting写的一个小游戏:Network Bomb
    wxwidgets学习与使用备忘录三(烦恼与便捷解决方案篇)
    regsvr32简介
    cocos2dx for XNA
    使用wxformbuilder进行wxwidgets的快速开发
    wxwidgets学习与使用备忘录一(下载、安装、配置篇)
  • 原文地址:https://www.cnblogs.com/youxin/p/8833514.html
Copyright © 2011-2022 走看看