c++---构造函数以及new和delete的使用

2023-05-16

目录

一、构造函数和析构函数的语法

 二、构造函数的分类和调用

 三、拷贝构造函数的调用时机

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(使用前将#替换为@)

c++---构造函数以及new和delete的使用 的相关文章

  • js中获取时间new Date()详细介绍

    1 var myDate 61 new Date Date 返回当日的日期和时间 getDate 从 Date 对象返回一个月中的某一天 1 31 getDay 从 Date 对象返回一周中的某一天 0 6 getMonth 从 Date
  • dedecms普通文章栏目改成自定义内容模型办法

    在织梦后台 程序 SQl命令工具 INSERT INTO addon18 aid typeid redirecturl userip body SELECT aid typeid redirecturl userip body FROM a
  • C ++的单例模式

    单例模式 对应一个类只能生成一个对象 include
  • 删除表和截断表命令之间的区别是什么?

    删除表和截断表命令之间的区别是什么 此问题提交于2004年11月23日 表删除包括表的定义和关联对象 规则 索引 约 触发器 主键 等 很明显 一旦表被删除 那么表中包含的所有的数据行都会被一同删除 truncate table 命令则仅仅
  • 多表可更新视图的实现

    多表关联后的数据能保证主键唯一的视图是可直接做更新 不需要用触发器实现 多表视图的定义 当视图的数据源只有一张数据表 则该视图为单表视图 当视图的数据源是多张数据表 则该视图为多表视图 可更新视图的定义 在绝大多数人的概念中 视图是只读的
  • 查询及删除重复记录的方法

    一 1 查找表中多余的重复记录 重复记录是根据单个字段 peopleId 来判断 select from people where peopleId in select peopleId from people group by peopl
  • Email Error - You have exceeded the storage limit on your mailbox

    Description You may receive an error You have exceeded the storage limit on your mailbox Delete some items from your mai
  • 私有构造函数

    通常我们都将构造函数的声明置于public区段 假如我们将其放入private区段中会发生什么样的后果 没错 我也知道这将会使构造函数成为私有的 这意味着什么 我们知道 当我们在程序中声明一个对象时 编译器为调用构造函数 如果有的话 而这个
  • 基数排序比快速排序快

    最近在关于算法的书籍 本以为以前看过的算法书都说快速排序是最好的排序算法 也没有想过 闲着无聊变写了一个关于基数排序的算法简单分析了一下应该时间复杂度比快速排序 小 于是编程实现果然结果要比快速排序 快 对两者都 1000000个数排序快速
  • 验证实例的有效性与类型的判断

    我们常常会用到指针变量 指针只有赋值以相应的实例才有意义 怎么判断指针引用实例的有效性是我们经常面对的一个问题 我现在 只知道两种方法 列举如下 1 ASSERT VALID pMyObject ASSERT VALID 要判断的类必须是C
  • new与默认构造函数

    class A public A int i int 0 private int a b class B public 无需构造函数 因为数据成员的全部为public int a b c int main A a 3 B b 1 2 3 A
  • 图遍历

    第七章 图 7 14 Status Build AdjList ALGraph G 输入有向图的顶点数 边数 顶点信息和边的信息建立邻接表 InitALGraph G scanf d v if v lt 0 return ERROR 顶点数
  • ASCII表

    http office microsoft com zh cn assistance HA011331362052 aspx ASCII 打印字符 数字 32 126 分配给了能在键盘上找到的字符 当您查看或打印文档时就会出现 数字 127
  • 柯理化、mergeOptions、new的实现原理、reduce、flat

    1 什么是反柯理化 怎么实现 反柯里化 是一个泛型化的过程 它使得被反柯里化的函数 可以接收更多参数 Function prototype unCurrying function var that this return function
  • OpenBSD cvsup更新

    安装了 OpenBSD 后你会发现它很小个 只有500多M 当然里面只有ssh sendmail功能 dev wd0a 130M 38 8M 84 7M 31 dev wd0h 95 5G 16 0K 90 8G 0 home dev wd
  • C++中前置声明的应用与陷阱

    前置声明的使用 有一定C 开发经验的朋友可能会遇到这样的场景 两个类A与B是强耦合关系 类A要引用B的对象 类B也要引用类A的对象 好的 不难 我的第一直觉让我写出这样的代码 A h include B h class A B b publ
  • 非printf形式打印各种数据类型的十六进制和二进制

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家提出意见 一起讨论 一 源码实现 为了适配各种数据类型 且可以通过sizeof得到此类型的大小 所以这里采用模板形式开发 以下是实现此功能的源码
  • ASCII码详解

    ASCII码表 ASCII码大致可以分作三部分組成 第一部分是 ASCII非打印控制字符 第二部分是 ASCII打印字符 第三部分是 扩展ASCII打印字符 第一部分 ASCII非打印控制字符表 ASCII表上的数字0 31分配给了控制字符
  • memset in C++ and C

    definition memset是计算机中C C 语言函数 将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值 第一个值为指定的内存地址 块的大小由第三个参数指定 这个函数通常为新申请的内存做初始化工作 其返回值
  • 解除Discuz!X2的15分钟锁定

    第一种方法 清两个failedlogin空表 解除用户锁定 mysql gt delete from pre common failedlogin Query OK 1 row affected 0 02 sec 解除UC用户锁定 mysq

随机推荐