C++构造函数的初始化列表详解

目录
  • 1.问题
  • 2.解决方法(初始化列表)
  • 3.顺序问题
  • 总结

1.问题

class A {
private:
	int m_a;
public:
	A(int a) {
		cout << "A(int a)......." << endl;
		m_a = a;
	}
	void print() {
		cout <<"m_a=" << m_a << endl;
	}
};
class B {
private:
	int m_b;
	A m_a1;
	A m_a2;
public:
	B(A& a1,A& a2, int b)
	{
		m_b = b;
		m_a1(a1);//此处调用A的拷贝函数会报错
		m_a2(a2);//此处调用A的拷贝函数会报错
	}
};

错误:

2.解决方法(初始化列表)

将class B构造函数改写为:

public:
	B(A& a1,A& a2, int b) :m_a1(a1),m_a2(a2)//构造函数的初始化列表
	{
		m_b = b;
	}
};

完整代码如下:

#include <iostream>
using namespace std;
class A {
private:
	int m_a;
public:
	A(int a) {
		cout << "A(int a)......." << endl;
		m_a = a;
	}
	void print() {
		cout <<"m_a=" << m_a << endl;
	}
	A(const A& another) {
		m_a = another.m_a;
	}
	~A() {
		cout << "~A()......" << endl;
	}
};
class B {
private:
	int m_b;
	A m_a1;
	A m_a2;
public:
	B(A& a1,A& a2, int b) :m_a1(a1),m_a2(a2)//构造函数的初始化列表,调用拷贝构造
	{
		cout << "B(A& a1,A& a2, int b)......." << endl;
		m_b = b;
	}
	~B() {
		cout << "~B()......." << endl;
		cout << "m_b=" << m_b  << endl;
		cout << "A m_a1" << endl;
		m_a1.print();
		cout << "A m_a2" << endl;
		m_a2.print();
	}
};
int main(int argc, char** argv) {
	A a1(1), a2(2);
	B b1(a1, a1, 3);
}

运行结果:

3.顺序问题

构造对象成员的顺序跟初始化列表的顺序无关,而是跟成员对象定义的顺序有关。(面试会问)

例子:

class A {
private:
	int m_a;
public:
	A(int a) {
		cout << "A(int a)......." <<a<< endl;
		m_a = a;
	}
	void print() {
		cout <<"m_a=" << m_a << endl;
	}
	A(const A& another) {
		m_a = another.m_a;
	}
	~A() {
		cout << "~A()......"<< endl;
	}
};
class B {
private:
	int m_b;
	A m_a2;
	A m_a1;
public:
	B(int a1, int a2, int b) :m_a1(a1), m_a2(a2)//调用有参构造函数
	{
		cout << "B(int a1, int a2, int b)......." << endl;
		m_b = b;
	}
	~B() {
		cout << "~B()......." << endl;
	}
};
int main(int argc, char** argv) {
	B b2(1, 2, 3);
}

结果:

跟下面顺序有关:

private:
	A m_a2;
	A m_a1;

跟下面顺序无关:

B(int a1, int a2, int b) :m_a1(a1), m_a2(a2)//调用有参构造函数

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • c++ 构造函数的初始化列表

    首先,运行下图中的C++代码,输出是什么? 复制代码 代码如下: class A{private: int n1; int n2;public: A(): n2(0) , n1(n2 + 2) { } void Print() {  cout<<"n1:"<<n1<<",n2:"<<n2<<endl; }};int main(void){ A a; a.Print(); return 0;} 答案:输出n1

  • c++基础语法:构造函数初始化列表

    C++为类中提供类成员的初始化列表 类对象的构造 顺序是这样的:1.分配内存,调用构造函数 时,隐式/显示的初始化各数据 成员2.进入构造函数后在构造函数中执行一般计算 使用初始化列表有两个原因: 1.必须这样做:如果我们有一个类成员,它本身是一个类或者是一个结构,而且这个成员它只有一个带参数的构造函数,而没有默认构造函数,这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错. 复制代码 代码如下: class  ABC  .

  • 关于C++中构造函数初始化成员列表的总结

    1.只能在构造函数初始化列表初始化的成员变量的类型? a.const成员变量 b.引用类型的成员变量 c.static不能在初始化列表中进行初始化 d.类成员变量中有自定义类型的变量最好在初始化列表中进行初始化 2.初始化列表的顺序? 初始化列表的初始化顺序是依据类成员变量定义的顺序来决定的. 3.关于static const是否应该在初始化成员列表中初始化? static const为全局静态常量,全局的意思是该变量属于整个类而非某个类实例,所以不能再初始化列表中进行初始化. 以上就是小编为大

  • C++构造函数的初始化列表详解

    目录 1.问题 2.解决方法(初始化列表) 3.顺序问题 总结 1.问题 class A { private: int m_a; public: A(int a) { cout << "A(int a)......." << endl; m_a = a; } void print() { cout <<"m_a=" << m_a << endl; } }; class B { private: int m_

  • C++类与对象深入之运算符重载与const及初始化列表详解

    目录 一:运算符重载 相等运算符重载 赋值运算符重载 小于运算符重载 二:const成员 const修饰类的成员函数 三:cin.cout重载 四:初始化列表 构造函数赋初值 初始化列表 explicit关键字 一:运算符重载 C++为了增强代码的可读性引入了运算符的重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型以及参数列表,其返回值类型与参数列表与普通函数类似. 函数名字为:关键字operator后面接需要重载的运算符符号 函数原型:返回值类型 operator操作符(参数列表)

  • C++ 初始化列表详解及实例代码

    C++ 初始化列表 何谓初始化列表 与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段.在C++中,struct和class的唯一区别是默认的访问性不同,而这里我们不考虑访问性的问题,所以下面的代码都以struct来演示. struct foo { string name ; int id ; foo(string s, int i):name(s), id(i){} ; // 初始化列表 }; 构造函数的两个执行

  • Java中初始化块详解及实例代码

    Java中初始化块详解 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员. 非静态初始化块:在每个对象生成时都会被执行一次,可以初始化类的实例变量. 非静态初始化块会在构造函数执行时,且在构造函数主体代码执行之前被运行. 括号里的是初始化块,这里面的代码在创建Java对象时执行,而且在构造器之前执行! 其实初始化块就是构造器的补充,初始化块是

  • C++中静态初始化数组与动态初始化数组详解

    静态初始化的数组的长度必须是在程序中确定的常数,不能是由用户输入的变量 例子: int a[10];//正确 Student stud[10];//正确:Student是一个学生类 int n;cin>>n;int a[n];//错误 int n;cin>>n;Student stud[n];//错误:Student是一个学生类 动态初始化数组可以使用用户输入的变量作为数组的长度. 例子: int n; cin>>n; int *a=new int[n];//这样整数数

  • C++中构造函数与析构函数的详解及其作用介绍

    目录 构造函数 默认构造函数 有参构造函数 析构函数 析构函数例子 析构函数执行时机 局部对象 全局对象 构造函数 构造函数 (constructor) 是一种特殊的成员函数. 它会在每次创建类的新对象时执行. 构造函数的名称与类的名称是完全相同的, 并且不会返回任何类型. 构造函数可用于为某些成员变量设置初始值. 格式: Class::Class(); // 构造函数 默认构造函数 如果用户自己没有定义构造函数, C++ 系统会自动生成一个默认构造函数. 这个构造函数体是空的, 没有参数, 不

  • Java数据结构之散列表详解

    目录 介绍 1 散列表概述 1.1 散列表概述 1.2 散列冲突(hash collision) 2 散列函数的选择 2.1 散列函数的要求 2.2 散列函数构造方法 3 散列冲突的解决 3.1 分离链接法 3.2 开放定址法 3.3 再散列法 4 散列表的简单实现 4.1 测试 介绍 本文详细介绍了散列表的概念.散列函数的选择.散列冲突的解决办法,并且最后提供了一种散列表的Java代码实现. 数组的特点是寻址容易,插入和删除困难:而链表的特点是寻址困难,插入和删除容易.而对于tree结构,它们

  • Java可变参数列表详解

    Java可变参数列表详解 1.接受的传入参数情况: 如public void test(String ...args){...} 1)不使用参数,如test() 2)使用一个或多个参数,如test("1"); test("1","2"); 3)使用数组 test(new String[]{"1","2"}); 2.方法内部访问参数: 在test方法内部,我们可以像使用数组的访问方式一样来访问参数args.如

  • Struts2中实现web应用的初始化实例详解

    Struts2中实现web应用的初始化实例详解 在JavsSE中,main方法为应用提供了入口,而在Android中,我们可以使用Application对于整个应用的生命周期进行管理,那么在基于Struts2的JavaEE应用中,如何实现类似的功能呢. 其中一种比较好的方式,是通过实现ServletContextListener接口进行坚挺,重写contextInitialized方法,实现自己需要进行的初始化操作,之后在web.xml中添加相应的listner,tomcat在启动服务时会调用相

随机推荐