构造函数
- 构造函数长什么样子
- 构造函数和类名相同
- 没有返回值
- 如果不写构造函数,任何类中都存在一个默认的构造函数
- 默认构造函数是无参的
- 当我们自己写了构造函数的时候,默认的构造函数就不存在了
- 构造函数在构造对象的时候调用
- 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;
}
谢谢大家的阅读,新手上路,如有不足之处请及时指出,我好纠正,万分感激~