C++知识梳理四构造函数

构造函数

  • 构造函数长什么样子
    • 构造函数和类名相同
    • 没有返回值
    • 如果不写构造函数,任何类中都存在一个默认的构造函数
      • 默认构造函数是无参的
      • 当我们自己写了构造函数的时候,默认的构造函数就不存在了
    • 构造函数在构造对象的时候调用
    • delete(关键字)可以用来删掉默认的构造函数
    • 指定使用默认的无参构造函数的时候,可以使用default(关键字)来说明
    • 不写构造函数也可以用来构造对象,因为存在一个默认的构造函数,所以可以构造无参对象
#include<iostream>
#include<string>
using namespace std;
class MM{
public:
	//MM()=delete	删除默认的构造函数
	MM()=default{
	cout<<"无参的默认构造函数"<<endl;
	}
	MM(string _name, int _age){
	cout<<"有参数的构造函数"<<endl;
	name=_name;
	age=_age;
	}	
protected:
	string name;
	int age;
};
  • 构造函数允许构造函数调用另一个构造函数,但是只能使用初始化参数列表的写法来实现
    初始化参数列表的写法:构造函数名(参数1,参数2,…):成员1(参数1),成员2(参数2),…{},避免形参名和数据成员名相同导致的问题
#include<iostream>
#include<string>
using namespace std;
class MM {	
public:
	MM(string name, int age) :name(name), age(age) {}
	MM():MM("小芳", 19) {
	}
	void print() {
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main(){
	MM mm;
	mm.print();
	return 0;
}
  • 构造函数是干嘛的
    • 构造函数是用来构造对象的
#include<iostream>
#include<string>
using namespace std;
class MM {	
public:
	MM(string name, int age) :name(name), age(age) {}
	void print() {
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main(){
	MM mm("小芳"19);
	mm.print();
	return 0;
}
  • 构造函数更多是用来初始化数据成员的
#include<iostream>
#include<string>
using namespace std;
class MM {	
public:
	MM(string name, int age) :name(name), age(age) {}
	void print() {
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main(){
	MM mm("小芳"19);
	mm.print();
	return 0;
}
  • 构造函数可以重载和缺省,是为了构造不同长相的对象

构造函数的重载

#include<iostream>
#include<string>
using namespace std;
class Boy {
public:
	Boy(string name) :name(name) {
		cout << name <<endl;
	}
	Boy(string name, int age) :name(name), age(age) {
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main(){
	Boy boy1("小芳");
	Boy boy2("小丽",20);
	return 0;
}

构造函数的缺省

#include<iostream>
#include<string>
using namespace std;
class MM2{
public:
	MM2(string name="",int age=0,int ID=0){
	cout<<name<<"\t"<<age<<"\t"<<ID<<endl;
}
protected:
	string name;
	int age;
	int ID;
};
int main(){
MM2 mm1;
MM2 mm2("熊四",201);
MM2 mm3("熊五",203,20112245);
}

析构函数

  • 析构函数长什么样子
    • 无返回值,无参数,不可以被重载
    • 函数名:~类名
    • 不写析构函数会存在一个默认的析构函数
    • 析构函数不需要自己调用,在对象死亡前会自己调用析构函数
  • 析构函数可以用来干嘛
    • 当类中的成员是指针,并且动态内存申请的时候需要手动调用析构函数,用来释放堆区内存
#include<iostream>
#include<string>
# include<cstring>
using namespace std;
class MM{
public:
	MM(const char *pName,int age):age(age){
		name=new char[strlen(pName)+1];
		strcpy_s(name,strlen(pName)+1,pName);
		cout<<"我叫做构造函数"<<endl;
	}
	viod print(){
	cout<<name<<"\t"<<age<<endl;
	}
	~MM(){
	delete[]name;
	cout<<"我叫做析构函数"<<endl;
}
protected:
char *name;
int age;
};
int main() {
	MM mm("小芳",18);
	mm.print();
}

拷贝构造函数

  • 拷贝构造函数也是构造函数,长相和构造函数一样的,只是参数是固定,只有唯一的一个参数,作用是是对对象引用
#include<iostream>
#include<string>
using namespace std;
class MM{
public:
	MM(string name,int age):name(name),age(age){
	cout<<"我叫做构造函数"<<nedl;
	}
	MM(const MM& mm){
	name=mm.name;
	age=mm.age;	
	cout<<"我叫做拷贝构造函数"<<endl;
}
	void print(){
	cout<<name<<"\t"<<age<<endl;
	}
protected:
string name;
int age;
};
int main(){

	MM mm("小芳", 18);
	mm.print();
	MM mm2(mm);
	mm2.print();
}
  • 不写拷贝构造函数,也存在一个默认的拷贝构造函数
  • 拷贝构造函数的作用是通过以个对象去初始化另一个对象,构造匿名对象的时候,匿名对象是一个临时对象,要加const修饰
#include<iostream>
#include<string>
using namespace std;
class MM {
public:
	MM ()=default;
	MM(string name, int age) :name(name), age(age) {
		cout << "我叫做构造函数" << endl;
	}
	MM(const MM& mm) {
		name = mm.name;
		age = mm.age;
		cout << "我叫做拷贝构造函数" << endl;
	}
	void print() {
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
int main(){
	MM mm("小芳", 18);
	mm.print();
	MM mm2(mm);
	mm2.print();
	MM temp= MM("匿名对象", 19);	
}
  • 还有一种情况,在函数的传参的时候也是调用拷贝构造函数
#include<iostream>
#include<string>
using namespace std;
class MM {
public:
	MM ()=default;
	MM(string name, int age) :name(name), age(age) {
		cout << "我叫做构造函数" << endl;
	}
	MM(const MM& mm) {
		name = mm.name;
		age = mm.age;
		cout << "我叫做拷贝构造函数" << endl;
	}
	void print() {
		cout << name << "\t" << age << endl;
	}
	void printdata(MM mm) {
		mm.print();	
	}
protected:
	string name;
	int age;
};
int main(){
	MM mm("小芳", 18);
	mm.print();
	MM mm2(mm);
	mm2.print();
	MM temp= MM("匿名对象", 19);
	temp.print();
	mm.printdata(mm);
}

深浅拷贝

  • 浅拷贝,没有写拷贝构造函数,默认的拷贝构造函数都是浅拷贝,浅拷贝存在了一种析构问题
#include<iostream>
#include<string>
# include<cstring>
using namespace std;
class MM{
public:
	MM(const char *pName,int age):age(age){
		name=new char[strlen(pName)+1];
		strcpy_s(name,strlen(pName)+1,pName);
		cout<<"我叫做构造函数"<<endl;
	}
	viod print(){
	cout<<name<<"\t"<<age<<endl;
	}
	~MM(){
	delete[]name;
	cout<<"我叫做析构函数"<<endl;
}
protected:
char *name;
int age;
};
int main(){
	MM mm("baby",19);
	MM girl(mm);//浅拷贝拷贝构造mm函数
	MM girl2=mm;//这样也是浅拷贝拷贝构造mm函数
}
  • 这样写会存在问题(内存重复释放问题),所以有了深拷贝,再new一段内存
#include<iostream>
#include<string>
# include<cstring>
using namespace std;
class MM{
public:
	viod print(){
		cout<<name<<"\t"<<age<<endl;
		}
	MM(const char *pName,int age):age(age){
		name=new char[strlen(pName)+1];
		strcpy_s(name,strlen(pName)+1,pName);
		cout<<"我叫做构造函数"<<endl;
	}
	MM(const MM& object){
		name = new char[strlen(object.name) + 1];
		strcpy_s(name, strlen(object.name) + 1, object.name);		
		cout << "我叫做拷贝构造函数" << endl;
		age = object.age ;
	
	~MM(){
	delete[]name;
	cout<<"我叫做析构函数"<<endl;
	}
protected:
char *name;
int age;
};
int main(){
	MM mm("baby",19);
	MM girl(mm);
	MM girl2=mm;
}

谢谢大家的阅读,新手上路,如有不足之处请及时指出,我好纠正,万分感激~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值