目录
一、构造函数和析构函数的语法
二、构造函数的分类和调用
三、拷贝构造函数的调用时机
1、用已经创建好的对象来初始化新的对象
2、用值传递的方式 给函数参数传值
3、以值的方式 返回局部对象
四、构造函数调用规则
五、初始化列表
六、类对象做类中成员
七、new和delete的使用
一、构造函数和析构函数的语法
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Person {
public:
//构造函数
//没有返回值 不用写void
//函数名和类名相同
//可以有参数 可以发生重载
//构造函数 由编译器自动调用一次 无需手动调用
Person()
{
cout << "Person的构造函数调用" << endl;
}
//析构函数
//没有返回值 不需要void
//函数名和类名相同 但是在前面要加~
//不可以有参数 不可以发生重载
//析构函数 由编译器自动调用一次 无需手动调用
~Person()
{
cout << "Person的析构函数调用" << endl;
}
};
void test01()
{
Person p;
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
二、构造函数的分类和调用
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
//构造函数分类
//参数: 无参构造(默认构造)函数 和 有参构造
//类型: 普通构造函数 拷贝构造函数
class Person {
public:
//无参构造函数
Person()
{
cout << "Person的默认构造函数调用" << endl;
}
//有参构造函数
Person(int a)
{
m_Age = a;
cout << "Person的有参构造函数调用" << endl;
}
//拷贝构造函数
Person(const Person& p)
{
cout << "Person的拷贝构造函数调用" << endl;
m_Age = p.m_Age;
}
~Person()
{
cout << "Person的析构函数调用" << endl;
}
int m_Age;
};
void test01()
{
//Person p;
1、括号法
//Person p1(20);
//Person p2(p);
//注意事项一
//不要用括号法 调用无参构造函数 Person p3() 编译器会认为这是一个函数声明
//2、显示法 打印结果两个析构函数调用 第一个是p4的 因为保存在栈上 先入后出
//Person p3 = Person(20); //有参构造
//Person p4 = Person(p3); //拷贝构造
//
//Person(10); //匿名对象 特点: 当前执行完立刻释放
//注意事项二
//不要用拷贝构造函数 初始化 匿名对象
//Person(p3) - > Person p3; //重定义
//3、隐式法 不推荐使用 可阅读性不高
Person p5 = 10; //Person(10)
Person p6 = p5; //Person(p5)
}
int main()
{
//Person P(18);
//Person P2(P);
//cout << "P2.m_Age = " << P2.m_Age << endl;
test01();
system("pause");
return EXIT_SUCCESS;
}
三、拷贝构造函数的调用时机
1、用已经创建好的对象来初始化新的对象
void test01()
{
Person p1(20);
Person p2 = Person(p1);
cout << "p2的年龄:" << p2.m_Age << endl;
}
输出:
2、用值传递的方式 给函数参数传值
void doWork(Person p)
{
}
void test02()
{
Person p1(100);
doWork(p1);
}
输出:
值传递的本质就是拷贝构造函数的调用
3、以值的方式 返回局部对象
Person doWork2()
{
Person p;
return p;
}
void test03()
{
Person p = doWork2();
}
四、构造函数调用规则
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
//1、编译器会给一个类 至少添加三个函数 默认构造(空实现) 析构函数(空实现) 拷贝构造(值拷贝)
//2、如果我们提供了有参构造函数 编译器就不会为我们提供默认构造函数 但是依然会提供拷贝构造函数
//3、如果我们提供了拷贝构造函数 编译器就不会为我们提供其他任何函数
class Person {
public:
Person()
{
cout << "默认构造函数调用" << endl;
}
Person(int age)
{
m_Age = age;
cout << "有参构造函数调用" << endl;
}
/*Person(const Person& p)
{
m_Age = p.m_Age;
cout << "拷贝构造函数调用" << endl;
}*/
~Person()
{
cout << "析构函数调用" << endl;
}
int m_Age;
};
void test01()
{
Person p1;
p1.m_Age = 22;
Person p2(p1);
cout << "p2.Age = " << p2.m_Age << endl;
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
五、初始化列表
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Text {
public:
//Text():m_a(10), m_b(20), m_c(30) //这里值就写死了
//{
//}
//构造函数的名称后 属性(值) 属性(值) .....
Text(int a, int b, int c) :m_a(a), m_b(b), m_c(c)
{
}
int m_a;
int m_b;
int m_c;
};
void test01()
{
//Text p;
Text p(10, 20, 30);
cout << "p.m_a = " << p.m_a << endl;
cout << "p.m_b = " << p.m_b << endl;
cout << "p.m_c = " << p.m_c << endl;
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
六、类对象做类中成员
当其他类对象作为本类成员 先构造其他类对象 再构造自身 析构的顺序和构造相反
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Phone {
public:
Phone(string pName)
{
m_Phone = pName;
cout << "phone有参构造调用" << endl;
}
~Phone()
{
cout << "phone析构函数调用" << endl;
}
string m_Phone;
};
class Game {
public:
Game(string gName)
{
m_Game = gName;
cout << "Game有参构造调用" << endl;
}
~Game()
{
cout << "Game析构函数调用" << endl;
}
string m_Game;
};
class Person {
public:
Person(string Name, string pName, string gName):m_Name(Name),m_phone(pName),m_game(gName)
{
cout << "person有参构造调用" << endl;
}
void Play_Game()
{
cout << m_Name << "拿着" << m_phone.m_Phone << "玩" << m_game.m_Game << endl;
}
~Person()
{
cout << "Person析构函数调用" << endl;
}
string m_Name;
Phone m_phone;
Game m_game;
};
//当其他类对象作为本类成员 先构造其他类对象 再构造自身 析构的顺序和构造相反
void test01()
{
Person p("张三","华为", "王者");
p.Play_Game();
}
int main()
{
test01();
system("pause");
return EXIT_SUCCESS;
}
输出:
test01中再添加一个:
void test01()
{
Person p("张三","华为", "王者");
p.Play_Game();
Person p2("李四", "苹果", "文明6");
p2.Play_Game();
}
输出:
七、new和delete的使用
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Person {
public:
Person()
{
cout << "默认构造函数调用" << endl;
}
Person(int a)
{
cout << "有参构造函数调用" << endl;
}
~Person()
{
cout << "析构函数调用" << endl;
}
};
//malloc 和 new 的区别
//malloc和free属于库函数 new和delete属于关键字
//malloc不会调用构造函数 new会调用构造函数
//malloc返回void * 要强制转换 new返回创建对象的指针
void test01()
{
Person* p = new Person;
delete p;
}
//不要用void *去接受new出来的对象,利用void*无法调用析构函数
void test02()
{
void* p = new Person;
delete p;
}
//new开辟数组
void test03()
{
//int *pInt = new int[10];
//double* pD = new double[10];
//堆区开辟数组一定会调用默认构造函数
//Person* p = new Person[10];
//释放数组要加[]
//delete[] p;
//栈上开辟数组的时候可以没有默认构造函数
Person pArray[10] = { Person(10),Person(20) };
}
int main()
{
//test01();
//test02();
test03();
system("pause");
return EXIT_SUCCESS;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)