构造函数
-
构造函数 1.函数名和类名相同 2.没有返回值 3.如果不写构造函数,任何类中都存在一个默认的构造函数 -默认构造函数是无参的 -当我们直接写了构造函数,默认构造函数就不存在 4.构造函数在构造对象时候调用 5.delete可以用来删掉默认的函数 6.指定使用默认的无参构造函数,用default说明 7.允许构造函数调用另一个构造函数,只是要用初始化参数列表写法 8.初始化参数列表:只有构造函数有 -构造函数名(参数1,参数2,·····):成员1(参数1),成员2(参数2),·····{} -
构造函数用来干啥的 1.构造函数用来构造对象 2.构造函数更多是用来初始化数据成员 -
思考 1.为什么不写构造函数可以构造对象? 因为存在一个默认的构造函数,所以可以构造无参对象 2.构造函数重载为了什么? 为了构造不同的对象
#include <iostream>
using namespace std;
class MM
{
public://MM()=delete;删掉默认的构造函数
MM(string mmName, int mmAge)
{
name = mmName;
age = mmAge;
cout << "带参数的构造函数" << endl;
}
MM() = default;
void print()
{
cout << name << " " << age << endl;
}
protected:
string name="大瓜";
int age=20;
};
class Boy
{
public:
Boy() {}
Boy(string mName) { name = mName; }
Boy(string mName, int mage) { name = mName; age = mage; }
protected:
string name;
int age;
};
string girlName = "小瓜";
class student
{
public:
student(string mname = "", int mage = 18) :name(mname), age(mage)
{
cout << "初始化参数列表" << endl;
}
student(int mage) :name(girlName), age(mage) {}
protected:
string name;
int age;
};
class TT
{
public:
TT(string name, int age) :name(name), age(age) {}
TT() :TT("傻瓜", 18) {}
void print()
{
cout << name << "\t" << age << endl;
}
protected:
string name;
int age;
};
int main()
{
MM mm("小瓜", 18);
mm.print();
MM girl;
girl.print();
Boy boy1;
Boy boy2("小瓜");
Boy boy3("大瓜", 18);
TT tt;
tt.print();
return 0;
}
析构函数
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
class student
{
public:
student(const char* mname, int age) :age(age)
{
name = new char[sizeof(mname) + 1];
strcpy_s(name, sizeof(mname) + 1, mname);
}
~student()
{
delete[]name;
cout << "析构函数" << endl;
}
void print()
{
cout << name << "\t" << age << endl;
}
protected:
char* name;
int age;
};
int main()
{
student MM("小瓜",18);
MM.print();
return 0;
}
拷贝构造函数
-
拷贝构造函数也是构造函数,长相和构造函数一样,只是参数固定 1.拷贝构造函数唯一的参数是对对象引用 -
不写拷贝构造函数,也存在一个默认的拷贝构造函数 -
拷贝构造函数作用:通过一个对象去初始化另一个对象 -
什么时候调用拷贝构造? 1.当通过一个对象去创建出来另一个新的对象的时候需要调咏拷贝 -
拷贝构造什么时候需要加const修饰参数? 1.当存在匿名对象赋值操作的时候,必须要和加const修饰
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM() = default;
MM(string name, int age) :name(name), age(age) {}
void print()
{
cout << name << "\t" << age << endl;
}
MM(const MM& mm)
{
name = mm.name;
age = mm.age;
cout << "拷贝构造" << endl;
}
protected:
string name;
int age;
};
void printData(MM mm)
{
mm.print();
}
void printData2(MM& mm)
{
mm.print();
}
int main()
{
MM mm("小瓜", 18);
mm.print();
cout << "显示调用" << endl;
MM girl(mm);
girl.print();
cout << endl;
cout << "隐式调用" << endl;
MM girl2 = mm;
girl2.print();
cout << endl;
MM girl3;
girl3 = mm;
girl3.print();
cout << endl;
cout << "第一种调用形态" << endl;
printData(mm);
cout << "第二种调用形态" << endl;
printData2(mm);
cout << endl;
MM temp;
temp = MM("匿名",18);
temp.print();
cout << endl;
MM temp2 = MM("匿名", 199);
temp2.print();
return 0;
}
深浅拷贝
- 浅拷贝:默认的拷贝构造叫浅拷贝
- 深拷贝:拷贝构造函数中做new内存操作,并且做拷贝赋值的操作
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
class MM
{
public:
MM(const char* mname, int age) :age(age)
{
name = new char[strlen(mname) + 1];
strcpy_s(name, strlen(mname) + 1, mname);
}
void print()
{
cout << name << "\t" << age << endl;
}
MM(const MM& object):age(object.age)
{
name = new char[strlen(object.name) + 1];
strcpy_s(name, strlen(object.name) + 1, object.name);
}
~MM()
{
delete[]name;
name = nullptr;
}
protected:
char* name;
int age;
};
int main()
{
{
MM mm("小瓜", 18);
MM girl(mm);
MM gm = mm;
mm.print();
girl.print();
gm.print();
}
return 0;
}
构造和析构顺序问题
- 普通对象,构造和析构顺序相反
- new出来的对象,delete会直接调用析构函数
- static对象,当程序关闭的时候,生命周期才会结束,所以最后释放
#include <iostream>
#include <string>
using namespace std;
class MM
{
public:
MM(string = "x") :name(name)
{
cout << name;
}
~MM()
{
cout << name;
}
protected:
string name;
};
int main()
{
{
MM mm1("A");
static MM mm2("B");
MM* p3 = new MM("C");
MM mm4[4];
delete p3;
p3 = nullptr;
}
return 0;
}
|