C++笔记:构造函数


前言

构造函数(也叫构造器),在对象创建的时候自动调用,一般用于完成对象的初始化工作
构造函数与类同名,无返回值(void都不用写),可以由参数,可以重载,可以有多个构造函数
一旦自定义了构造函数,必须用其中一个自定义的构造函数来初始化对象


无参的构造函数

#include <iostream>
using namespace std;

class Person {

private:
	int m_age;
	int m_height;

public:

	Person() {
		cout << "无参构造函数:Person()" << endl;
		cout << "age=" << m_age << ",height=" << m_height << endl;
	}
};

int main() {

	//栈空间 
	Person person;

	Person person2;

	Person person3;

	return 0;
}

out为

无参构造函数:Person()
age=-858993460,height=-858993460
无参构造函数:Person()
age=-858993460,height=-858993460
无参构造函数:Person()
age=-858993460,height=-858993460

反汇编为

22: 	//栈空间 
    23: 	Person person;
00AF26A2  lea         ecx,[person]  
00AF26A5  call        Person::Person (0AF13F2h)  
    24: 
    25: 	Person person2;
00AF26AA  lea         ecx,[person2]  
00AF26AD  call        Person::Person (0AF13F2h)  
    26: 
    27: 	Person person3;
00AF26B2  lea         ecx,[person3]  
00AF26B5  call        Person::Person (0AF13F2h) 

倘若

Person() {
	    m_age = 0;
		m_height = 0;
		cout << "无参构造函数:Person()" << endl;
		cout << "age=" << m_age << ",height=" << m_height << endl;
	}

则out为

无参构造函数:Person()
age=0,height=0
无参构造函数:Person()
age=0,height=0
无参构造函数:Person()
age=0,height=0

有参的构造函数

#include <iostream>
using namespace std;

class Person {

private:
	int m_age;
	int m_height;

public:

	Person() {
		m_age = 0;
		cout << "无参构造函数:Person()" << endl;
		cout << "age=" << m_age  << endl;
	}
	Person(int age) {
		m_age = age;
		cout << "有参构造函数:Person(int age)" << endl;
		cout << "age=" << m_age << endl;
	}
	void display() {
		cout << "age is" << m_age << endl;
	}
};



int main() 
{
	//栈空间 
	Person person;//调用无参的构造函数
	person.display();

	Person person2(20);//调用有一个整型参数的构造函数
	person2.display();

	Person person3(30);
	person3.display();

	return 0;
}

out为

无参构造函数:Person()
age=0
age is0
有参构造函数:Person(int age)
age=20
age is20
有参构造函数:Person(int age)
age=30
age is30

查看反汇编

31: 	//栈空间 
    32: 	Person person;//调用无参的构造函数
00745812  lea         ecx,[ebp-10h]  
00745815  call        007413F2  
    33: 	person.display();
0074581A  lea         ecx,[ebp-10h]  
0074581D  call        00741442  
    34: 
    35: 	Person person2(20);//调用有一个整型参数的构造函数
00745822  push        14h  
00745824  lea         ecx,[ebp-20h]  
00745827  call        0074143D  
    36: 	person2.display();
0074582C  lea         ecx,[ebp-20h]  
0074582F  call        00741442  
    37: 
    38: 	Person person3(30);
00745834  push        1Eh  
00745836  lea         ecx,[ebp-30h]  
00745839  call        0074143D  
    39: 	person3.display();
0074583E  lea         ecx,[ebp-30h]  
00745841  call        00741442  

一旦自定义了构造函数,必须用其中一个自定义构造函数来初始化对象。

包含的含义是
①如果没有自定义构造函数,那么
在这里插入图片描述
只能写成
在这里插入图片描述
②如果Person person2(20)则表示调用有一个整型参数的构造函数
如果Person person2(20,30)则表示调用有两个整型参数的构造函数


全局区、栈空间和通过new申请的堆空间都会调用构造函数

代码

#include <iostream>
using namespace std;

class Person {

private:
	int m_age;
	int m_height;

public:

	Person() {
		m_age = 0;
		cout << "无参构造函数:Person()" << endl;
		cout << "age=" << m_age  << endl;
	}
	
};

Person g_person; //全局区

int main() 
{
	//栈空间 
	Person person;
	//堆空间
	Person* p = new Person;

	cout << " sizeof(Person) = " << sizeof(Person) << endl;  //Person类的size是8
	delete p;
	
	
	return 0;
}

out为

无参构造函数:Person()
age=0
无参构造函数:Person()
age=0
无参构造函数:Person()
age=0
 sizeof(Person) = 8

在这里插入图片描述

24: 	//栈空间 
    25: 	Person person;
00EA3AAA  lea         ecx,[person]  
00EA3AAD  call        Person::Person (0EA1483h)  //调用构造函数
    26: 	//堆空间
    27: 	Person* p = new Person;
00EA3AB2  push        8  
00EA3AB4  call        operator new (0EA1140h)  
00EA3AB9  add         esp,4  
00EA3ABC  mov         dword ptr [ebp-100h],eax  
00EA3AC2  mov         dword ptr [ebp-4],0  
00EA3AC9  cmp         dword ptr [ebp-100h],0  
00EA3AD0  je          main+85h (0EA3AE5h)  
00EA3AD2  mov         ecx,dword ptr [ebp-100h]  
00EA3AD8  call        Person::Person (0EA1483h)  //调用构造函数
00EA3ADD  mov         dword ptr [ebp-114h],eax  
00EA3AE3  jmp         main+8Fh (0EA3AEFh)  
00EA3AE5  mov         dword ptr [ebp-114h],0  
00EA3AEF  mov         eax,dword ptr [ebp-114h]  
00EA3AF5  mov         dword ptr [ebp-0F4h],eax  
00EA3AFB  mov         dword ptr [ebp-4],0FFFFFFFFh  
00EA3B02  mov         ecx,dword ptr [ebp-0F4h]  
00EA3B08  mov         dword ptr [p],ecx  

通过malloc申请堆空间不会调用构造函数

代码如下:

#include <iostream>
using namespace std;

class Person {

public:
	int m_age;

	Person() {
		m_age = 0;
		cout << "无参构造函数:Person()" << endl;
		cout << "age=" << m_age  << endl;
	}
	
	void run() {
		cout << "Person::run() - " << m_age << endl;
	}
};
//全局区
Person g_person;

int main() 
{
	//栈空间 
	Person person;
	//堆空间
	Person* p = new Person;

	cout << " sizeof(Person) = " << sizeof(Person) << endl;  //Person类的size是8
	delete p;

	//堆空间
	Person* p2 = (Person*)malloc( sizeof(Person) );
	p2->m_age = 10;
	p2->run();
	
	free(p2);

	return 0;
}

out为

无参构造函数:Person()
age=0
无参构造函数:Person()
age=0
无参构造函数:Person()
age=0
 sizeof(Person) = 4
Person::run() - 10

malloc初始化的反汇编结果如下,可以看出并未调用构造函数

32: 	//堆空间
    33: 	Person* p2 = (Person*)malloc( sizeof(Person) );
00403B96  mov         esi,esp  
00403B98  push        4  
00403B9A  call        dword ptr [__imp__malloc (040E1D8h)]  
00403BA0  add         esp,4  
00403BA3  cmp         esi,esp  
00403BA5  call        __RTC_CheckEsp (04012F8h)  
00403BAA  mov         dword ptr [p2],eax  
    34: 	p2->m_age = 10;
00403BAD  mov         eax,dword ptr [p2]  
00403BB0  mov         dword ptr [eax],0Ah  
    35: 	p2->run();
00403BB6  mov         ecx,dword ptr [p2]  
00403BB9  call        Person::run (04014E7h)  //call了run函数
    36: 	
    37: 	free(p2);
00403BBE  mov         esi,esp  
00403BC0  mov         eax,dword ptr [p2]  
00403BC3  push        eax  
00403BC4  call        dword ptr [__imp__free (040E21Ch)]  
00403BCA  add         esp,4  
00403BCD  cmp         esi,esp  
00403BCF  call        __RTC_CheckEsp (04012F8h)  

如果没写构造函数

如果没写构造函数,编译器并不会为类生成空的无参的构造函数
在某些特定的情况下除外,查看以下代码

#include <iostream>
using namespace std;

struct Person {
	int m_age = 0;	//初始化;若没有初始化,就不会生成空的无参的构造函数
};
int main() 
{
	//栈空间 
	Person person;
	person.m_age = 10;

	return 0;
}

查看反汇编,可以看到调用了构造函数

13: 	//栈空间 
    14: 	Person person;
008D2D02  lea         ecx,[person]  
008D2D05  call        std::operator<<<std::char_traits<char> > (08D14ECh)  
    15: 	person.m_age = 10;
008D2D0A  mov         dword ptr [person],0Ah
008D14EC  jmp         Person::Person (08D2C90h)  //调用构造函数
008D2C90  push        ebp  
008D2C91  mov         ebp,esp  
008D2C93  sub         esp,0CCh  
008D2C99  push        ebx  
008D2C9A  push        esi  
008D2C9B  push        edi  
008D2C9C  push        ecx  
008D2C9D  lea         edi,[ebp-0CCh]  
008D2CA3  mov         ecx,33h  
008D2CA8  mov         eax,0CCCCCCCCh  
008D2CAD  rep stos    dword ptr es:[edi]  
008D2CAF  pop         ecx  
008D2CB0  mov         dword ptr [this],ecx  
008D2CB3  mov         eax,dword ptr [this]  
008D2CB6  mov         dword ptr [eax],0   // m_age = 0
008D2CBC  mov         eax,dword ptr [this]  
008D2CBF  pop         edi  
008D2CC0  pop         esi  
008D2CC1  pop         ebx  
008D2CC2  mov         esp,ebp  
008D2CC4  pop         ebp  
008D2CC5  ret  

注意事项和总结

1、class默认是private,struct默认是public,所以当需要在main函数中访问类中的成员变量时需要对成员变量的访问权限进行指明(即public)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值