构造函数
在任何类中都有一个默认的构造函数(无参);定义构造函数时,构造函数名和类名相同,并且没有返回值。
作用:构造函数用来构造对象,更多是用来初始数据成员。当写了构造函数,默认构造函数就不存在。
关键字:default(使用系统默认的无参构造函数,比自己写的要快一点)
delete(可以删除系统默认的无参构造函数)
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:
//Student = delete; //删除默认构造函数,无法创建对象
Student(string sname,int sAge) //创建构造函数
{
name = smage;
age = sAge;
cout << "构造函数" << endl;
}
Student() = default; //使用的是默认构造函数
protected:
string name = "小明";
int age = 14;
};
class Teacher
{
public:
//为了能构造不同长度的对象,给构造函数做函数缺省处理
Teacher(string tName = "李丽",int tName = 33)
{
name = tName;
age = tAge;
}
prorected:
string name;
int age;
};
int main()
{
//Student xiao; 构造无参的对象, 需要无参构造函数
Student xiao("小明",18);
Teacher t1;
Teacher t2("李逵");
Teacher t3("张峰",34);
return 0;
}
初始化参数列表:只有构造函数有
构造函数名(参数1,参数2,...):成员1(参数1),成员2(参数2),...{}
委托构造:构造函数可以调用另一个构造函数 初始化数据
#include<iostream>
using namespace std;
class MM
{
public:
MM(string mname = "",int mage = 0):name(mname),age(mage)
{
cout << "初始化参数列表" << endl;
//继承和类的组合必须采用初始化参数列表写法
}
//委托构造:构造函数可以调用另一个构造函数 初始化数据
MM():MM("默认",18){}
void print()
{
cout << name << '\t' << age << endl;
}
protected:
string name;
int age;
};
int main()
{
MM mm;
mm.print();
return 0;
}
析构函数
析构函数:无返回值、无参数、不写会默认的析构函数、不需要手动掉用,对象死亡之前会自动掉用析构函数、
析构函数名:~类名
析构函数作用:当类中的数据成员是指针时,并且动态申请内存就需要手写析构函数,但不需要手动掉用,手动掉用会导致二次释放问题,析构函数用来释放数据成员申请动态的内存
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class MM
{
public:
MM(coust char* pstr,int age):age(age)
{
str = new char[strlen(sptr)+1];
strcpy(str,pstr);
}
void print()
{
cout << str << '\t' << age << endl;
}
//析构函数
~MM();
protected:
char* str;
int age;
};
MM :: ~MM()
{
cout << "调用析构函数" << endl;
delete[] str;
}
int main()
{
{
MM mm("小芳",19);
//mm.~MM(); //手动掉用析构函数会导致二次释放
mm.print();
}
cout << "主函数" << endl;
//new一个对象时,只有delete 才会掉用析构函数
{
char*p = new MM("girl",18);
delete p;
}
return 0;
}
拷贝构造函数
拷贝构造函数也是构造函数,长相和构造函数一样,只是参数是固定的
拷贝构造函数唯一的参数是对对象的引用
不写拷贝构造函数,也会存在一个默认的拷贝构造函数
拷贝函数作用:通过一个对象去初始化另一个对象
当存在匿名对象赋值操作的时候,必须加const修饰
#include<iostream>
#include<string>
using namespace std;
class MM
{
public:
MM() = default;
MM(string name,int age):name(name),age(age){}
//拷贝构造
MM(const MM& mm) //匿名对象创建对象时候,一定要用const修饰
{
name = mm.name;
age = mm.age;
}
void print()
{
cout << name << '\t' << age << endl;
}
protected:
string name;
int age;
};
int main()
{
MM mm("小芳",18);
MM girl(mm); //拷贝构造:通过一个对象去初始化另一个对象
//匿名对象
MM temp = MM("默认",19);
return 0;
}
深拷贝和浅拷贝
浅拷贝:默认的拷贝构造叫做浅拷贝
深拷贝:拷贝构造函数中做了new内存操作,并且做拷贝赋值的操作
深拷贝:把一段申请动态内存的值拷贝到另一个新申请动态内存里面
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
class MM
{
public:
MM() = default;
MM(const char* mname,int mage):age(mage)
{
name = new char[strlen(mname)+1];
strcpy_s(name,strlen(mname)+1,mname);
age = mage;
}
~MM()
{
delete[] name;
}
void print()
{
cout << name << '\t' << age << endl;
}
//深拷贝
MM(const MM& object)
{
name = new char[strlen(object.name)+1];
strcpy_s(name,strlen(object.name)+1,object,name);
age = object.age;
}
protected:
char* name;
int age;
};
int main()
{
MM mm("GG",18);
MM girl(mm); //深拷贝
MM girl2 = mm; //深拷贝
return 0;
}
作业
#include<iostream>
#include<cstring>
using namespace std;
class myString
{
public:
myString(const char *pstr = "")
{
str = new char[strlen(pstr)+1];
strcpy(str,pstr);
}
myString(const myString& String)
{
str = new char[strlen(String.str)+1];
strcpy(str,String.str);
}
char* data()
{
char*ch = new char[strlen(str)+1];
strcpy(ch,str);
return ch;
}
char* c_str()
{
char*ch = new char[strlen(str)+1];
strcpy(ch,str);
return ch;
}
char* append(char* c)
{
return strcat(str,c);
}
int compare(char* ch)
{
int a = strlen(str);
for(int i = 0;i < a;i++)
{
if(str[i] > ch[i]) return 1;
}
return 0;
}
~myString()
{
delete [] str;
}
protected:
char *str;
};
int main()
{
myString str1;
myString str2 ("ILoveYou");
myString str3(str2);
myString str4 = str2;
cout << str2.c_str() << endl;
cout << str2.data() << endl;
string strOne = "one";
string strTwo = "two";
string strThree = strOne.append(strTwo);
cout << strThree << endl;
cout << strOne.compare(strOne) << endl;
return 0;
}