C++

对象初始化

Posted by persuez on July 17, 2018

对象初始化

C++中对象初始化是依靠constructor(常译为:构造函数)。这个特殊的函数的函数名与类名要相同,并且没有返回值。一般放在public域中,因为一般情况需要在类的外面声明类的变量并进行初始化。如:

class Stock {
public:
  Stock(int a) // constructor
  {
    _a = a;
  }
private:
  int _a;
};

其他的constructor的语法还有如:初始化表(很重要)。要知道的是,constructor可以进行重载。一个类中如果没有提供constructor,那么编译器会给它提供一个default constructor(没有形参的constructor),但是这个default constructor什么也不做;但是如果我们提供了一个或多个constructor(没有default constructor),那么编译器将不会帮我们提供default constructor,所以像上述Stock类的定义,有了一个有一个参数的constructor,所以下面用法将会出错:

class Stock {
public:
  Stock(int a) // constructor
  {
    _a = a;
  }
private:
  int _a;
};

int main()
{
    Stock s1; // 这个语句会调用default constructor,但是编译器找不到,所以会出错
    Stock *s2 = new Stock(2); // valid

    ...
}

初始化列表

这是一个很重要的constructor构造方式:

class Stock {
public:
  Stock(int a, string &s) // 初始化表
   _a(a), _s(s)
  {}
private:
  int _a;
  string _s;
};

注意: 初始化列表的初始化顺序只与成员声明的顺序有关,和constructor中的写的顺序无关。而且对于有自定义类对象(如string)的成员时,使用初始化列表效率会更高。因为如果在函数体中使用赋值操作,其实进行了两步,先调用default constructor,然后再进行赋值;而初始化列表只是调用了copy constructor。

注意点

  1. 对象使用之前必须初始化
  2. C++11可以在类声明成员变量时进行初始化。
  3. 常量数组要用枚举或static const变量
  4. C++对“定义于不同编译单元内的non-local static对象”的初始化顺序并无明确规定。详见《Effective C++》第三版条款04。
  5. 在constructor内阻止资源泄漏。详见《More Effective C++》条款10。