【C++grammar】C++类数据成员的初始化

287 阅读2分钟

目录

1、类成员的就地初始化example

class S { 
  int m = 7; // ok, copy-initializes m  
  int n(7);  // 错误:不允许用小括号初始化  
  std::string s{'a', 'b', 'c'}; // ok, direct list-initializes s
  std::string t{"Constructor run"}; // ok
  int a[] = {1,2,3}; // 错误:数组类型成员不能自动推断大小 
  int b[3] = {1,2,3}; // ok
  // 引用类型的成员有一些额外限制,参考标准
public:
  S() { } 
};

2、构造函数初始化

在这里插入图片描述
在这里插入图片描述

A data field is an object type (Object in Object / Embedded Object) (类的数据域是一个对象类型,被称为对象中的对象,或者内嵌对象)
The embedded object must be constructed before the body of ctor is executed (内嵌对象必须在被嵌对象的构造函数体执行前就构造完成)

class Time { /* Code omitted */ }
class Action {
public:
  Action(int hour, int minute, int second) {
    time = Time(hour, minute, second); //time对象应该在构造函数体之前构造完成
  }
private:
  Time time;
}; 
Action a(11, 59, 30);

解释time是Time的对象,是Action的内嵌对象
需要注意的地方:
在构造函数的函数体中,不可以初始化类的数据成员
构造函数的函数体执行之前,类中的数据成员必须完成初始化

3、默认构造函数:Default Constructor

默认构造函数是可以无参调用的构造函数,既可以是定义为空参数列表的构造函数,也可以是所有参数都有默认参数值的构造函数

class Circle1 {
public:
  Circle1() {      // 无参数
    radius = 1.0; /*函数体可为空*/
  }
private:
  double radius;
};
class Circle2 {
public:
  Circle2(double r = 1.0) // 所有参数都有默认值
    : radius{ r } {
  }
private:
  double radius;
};

在这里插入图片描述

4、举例

class Circle {
private:
    double radius;
public:
    double getArea() {
        return 3.14 * radius * radius;
    }
};
class Square {
private:
    double side;
public:
    double getArea() {
        return side * side;
    }
};
class Combo {
private:
    Circle c;
    Square s;

};

int main()
{
    Combo o{};
    cout<<o.c.getArea() << endl;
    return 0;
}

此时,c对象是个私有的,所以不能直接访问
在这里插入图片描述
有关代码:

class Circle {
private:
    double radius;
public:
    //指示编译器生成无参构造函数
    Circle() = default;
    //构造函数
    Circle(double r) {
        radius = r;
    }
    double getArea() {
        return 3.14 * radius * radius;
    }
};
class Square {
private:
    double side;
public:
    //指示编译器不构造默认构造函数
    //Square() = delete;
    //            私有数据成员side  double side
    Square(double side) :side{ side } {}
    //或者写成
    /*
        Square(double side)
        {
            this->side = side;
        }
    */
    double getArea() {
        return side * side;
    }
};
class Combo {
public:
    Circle c;
    Square s;
    //构造函数.内嵌对象的构造必须在构造函数体之前就完成了
    Combo() :s{1.0} {}
};

int main()
{
    Combo o{};
    cout<<o.c.getArea() << endl;
    return 0;
}

在这里插入图片描述

5、成员的初始化方法的优先级

在这里插入图片描述
一个成员同时有就地初始化和构造函数列表初始化,则就地初始化语句被忽略不执行