[基础知识]1.C++成员变量的初始化顺序?

版权声明:By TimepassbyZ 转载请注明出处! https://blog.csdn.net/TimepassbyZ/article/details/84894303

下列程序的执行结果分别是?

class A
{
private:
	int n1;
	int n2;
	
public:
	A():n2(0),n1(n2+2019){}
	void Print(){
		cout << "n1:" << n1 << ", n2:" << n2 << endl;  
	}
};
int main()
{
	A a;
	a.Print();
	
	return 0;
}
class B
{
private:
	int n1;
	int n2;
	
public:
	B(){
		n2 = 0;
		n1 = n2 + 2019;
	}
	void Print(){
		cout << "n1:" << n1 << ", n2:" << n2 << endl;  
	}
};
 
int main()
{
	B b;
	b.Print();
 
	return 0;
}
  • 答案:
    A. n1:随机数, n2:0
    B. n1:2019, n2:0

相关知识点:

  1. 初始化数据成员的两种方法:赋值法、列表法
class Complex{
private:
	double real;
	double image;
public:
	Complex(double r, double i); // 声明构造函数原型
 	...
};
/* 用赋值语句对数据成员赋初值 */
Complex::Complex(double r, double i){
	real = r;
	imag = i;
}
/* 用成员初始化列表对数据成员初始化 */
Complex::Complex(double r, double i):real(r),imag(i){}
  1. 成员变量的初始化顺序
    2.1 赋值法初始化顺序与构造函数中的成员变量的赋值顺序有关,与成员变量的定义顺序无关。
    2.2 列表法初始化顺序与构造函数外的成员变量的定义顺序有关,与初始化成员列表的顺序无关。
  2. const修饰的数据成员、引用类型的数据成员只能用初始化成员列表来初始化数据,不允许用赋值语句直接赋值。
  3. 成员变量在定义时不能初始化。
  4. static成员变量必须在类外初始化,而且应在定义对象之前进行。
  5. static成员变量属于类对象的集合,而不属于某一个对象。无论建立多少个类的对象,都只有一个静态数据成员的拷贝。从而实现了同一个类的不同对象之间的数据共享。
  6. 变量的初始化顺序:基类的静态变量或全局变量->派生类的静态变量或全局变量->基类的成员变量->派生类的成员变量

扩展:

  1. 构造函数是一种特殊的成员函数,主要用于为对象分配空间,进行初始化.
  2. 构造函数没有返回值。(不能说明为void类型
  3. 构造函数不能为虚函数。
  4. 构造函数的初始化顺序:
    首先,任何虚基类的构造函数按照它们被继承的顺序构造;
    其次,任何非虚基类的构造函数按照它们被继承的顺序构造;
    最后,任何成员对象的构造函数按照它们声明的顺序调用。
class OBJ1{
public:
	OBJ1(){ cout<<"OBJ1\n"; }
};
class OBJ2{
public:
	OBJ2(){ cout<<"OBJ2\n";}
}
class Base1{
public:
	Base1(){ cout<<"Base1\n";}
}
class Base2{
public:
	Base2(){ cout <<"Base2\n"; }
};
class Base3{
public:
	Base3(){ cout <<"Base3\n"; }
};
class Base4{
public:
	Base4(){ cout <<"Base4\n"; }
};
// 继承顺序
class Derived :public Base1, virtual public Base2,public Base3, virtual public Base4{
public:
	// 初始化列表
	Derived() :Base4(), Base3(), Base2(),Base1(), obj2(), obj1(){
		cout <<"Derived ok.\n";
	}
protected:
	// 声明顺序
	OBJ1 obj1;
	OBJ2 obj2;
};

int main()
{
	Derived aa; // 初始化
	cout <<"This is ok.\n";
	return 0;
}
  • 运行结果:
    Base2 // 虚拟基类按照被继承顺序初始化
    Base4 // 虚拟基类按照被继承的顺序
    Base1 // 非虚拟基类按照被继承的顺序初始化
    Base3 // 非虚拟基类按照被继承的顺序
    OBJ1 // 成员函数按照声明的顺序初始化
    OBJ2 // 成员函数按照声明的顺序
    Derived ok.
    This is ok.

参考文章
C++成员变量的初始化顺序问题
C++成员变量、构造函数的初始化顺序

猜你喜欢

转载自blog.csdn.net/TimepassbyZ/article/details/84894303
今日推荐