C++:数据成员的初始化和赋值


1. 默认初始化

#include <iostream>
#include <string>
using namespace std;
class A
{
public:
    int m;
    string s;
};

int main()
{
    A a1;
    cout << "----------------------------" << endl;
    cout << a1.m << endl;//类内内置类型未定义
    cout << a1.s << endl;//string默认初始化为空串
    cout << "----------------------------" << endl;
    return 0;
}

运行结果

  1. 当类中无任何构造函数和类内初始值时,编译器通过合成的默认构造函数来对数据成员进行默认初始化。
  2. 默认初始化时,变量被赋予的默认值由变量的类型和位置决定,函数体内和类内的内置类型不被初始化,即未定义。

2. 类内初始值(部分编译器不支持)

#include <iostream>
#include <string>
using namespace std;
class A
{
public:
    int m = 1;
    string s = "a";
};

int main()
{
    A a1;
    cout << "----------------------------" << endl;
    cout << a1.m << endl;
    cout << a1.s << endl;
    cout << "----------------------------" << endl;
    return 0;
}

运行结果

  1. 当类中无任何构造函数,但有类内初始值时,编译器在其合成的默认构造函数中,利用类内初始值来初始化数据成员。

3. 构造函数内赋值

#include <iostream>
#include <string>
using namespace std;
class A
{
public:
    A() //显式创建的构造函数
    {
        m = 2;
        s = "b";
    }
    int m = 1;
    string s = "a";
};

int main()
{
    A a1;
    cout << "----------------------------" << endl;
    cout << a1.m << endl;
    cout << a1.s << endl;
    cout << "----------------------------" << endl;
    return 0;
}

运行结果

  1. 在类内显式创建构造函数,在函数体赋值,其结果会覆盖类内初始值。
  2. 若成员是const、引用或某种未提供此默认构造函数的类类型时,其成员必须初始化,不能用该方法赋值。

4. 构造函数初始值列表

#include <iostream>
#include <string>
using namespace std;
class B //不含默认构造函数
{
public:
    int n;
    B(int x) //默认构造函数无参数,此构造函数不是默认构造函数
    {
        n = x;
    }
};

class A
{
public:
    A() : m1(10), m2(20), r(m2), b(40) //显示创建的构造函数
    {
        m1 = 100;
    }
    int m1 = 1;
    const int m2 = 2;  //const
    const int &r = m1; //引用
    B b;               //未提供默认构造函数
};

int main()
{
    A a1;
    cout << "----------------------------" << endl;
    cout << a1.m1 << endl;
    cout << a1.m2 << endl;
    cout << a1.r << endl;
    cout << a1.b.n << endl;
    cout << "----------------------------" << endl;
    return 0;
}

运行结果

  1. 若成员是const、引用或某种未提供此默认构造函数的类类型时,其成员必须通过构造函数初始值列表进行初始化。
  2. 优先级:默认初始化<类内初始值<构造函数初始值列表<构造函数赋值。数据成员的值会被优先级高的值覆盖。

注意:

#include <iostream>
#include <string>
using namespace std;
class B //不含默认构造函数
{
public:
    int n;
    B(int x, int y) //默认构造函数无参数,此构造函数不是默认构造函数
    {
        n = x * y;
    }
};

class A //类内初始值
{
public:
    int m1 = 1;
    const int m2 = 2; //const
    int &r = m1;      //引用
    B b = B(3, 4);    //未提供默认构造函数
};

int main()
{
    A a1;
    cout << "----------------------------" << endl;
    cout << a1.m1 << " " << a1.m2 << " " << a1.r << " " << a1.b.n << endl;
    a1.m1 = 0; //m1是int,可修改
    // a1.m2 = 0; //错误,m2是const int,不可修改
    a1.r = 5;       //r引用m1,对r的修改实际是对m1的修改
    a1.b = B(0, 0); //b是类类型,可赋值修改
    cout << a1.m1 << " " << a1.m2 << " " << a1.r << " " << a1.b.n << endl;
    cout << "----------------------------" << endl;

    A a2, a3; //a2.m2和a3.m2不可修改,且总是相等
    cout << a2.m2 << endl;
    cout << a3.m2 << endl;
    cout << "----------------------------" << endl;
    return 0;
}

运行结果

#include <iostream>
#include <string>
using namespace std;
class B //不含默认构造函数
{
public:
    int n;
    B(int x, int y) //默认构造函数无参数,此构造函数不是默认构造函数
    {
        n = x * y;
    }
};

class A //构造函数初始化列表
{
public:
    A() : m1(1), m2(2), r(m1), b(3, 4) {}                               //默认构造函数
    A(int i1, int i2, int x, int y) : m1(i1), m2(i2), r(m1), b(x, y) {} //普通构造函数

    int m1;
    const int m2; //const
    int &r;       //引用
    B b;          //未提供默认构造函数
};

int main()
{
    A a1;
    cout << "----------------------------" << endl;
    cout << a1.m1 << " " << a1.m2 << " " << a1.r << " " << a1.b.n << endl;
    a1.m1 = 0; //m1是int,可修改
    // a1.m2 = 0; //错误,m2是const int,不可修改
    a1.r = 5;       //r引用m1,对r的修改实际是对m1的修改
    a1.b = B(0, 0); //b是类类型,可赋值修改
    cout << a1.m1 << " " << a1.m2 << " " << a1.r << " " << a1.b.n << endl;
    cout << "----------------------------" << endl;

    A a2(1, 2, 3, 4), a3(10, 20, 30, 40); //a2.m2和a3.m2不可修改,但a2.m2和a3.m2可以不同
    cout << a2.m2 << endl;
    cout << a3.m2 << endl;
    cout << "----------------------------" << endl;
    return 0;
}

运行结果

  1. 当成员是const、引用或某种未提供此默认构造函数的类类型时,用类内初始值初始化,编译并未报错,程序正常运行。
  2. 使用类内初始值初始化const成员时,类的对象无法修改自己的const成员,不同的对象其const成员都是相等的,类内的const与类外的const并无区别。
  3. 使用构造函数初始值列表初始化const成员时,类的对象也无法修改自己的const成员,但不同的对象其const成员的值可以不同,符合类的用法。
发布了77 篇原创文章 · 获赞 25 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34801642/article/details/104873403