首页 > 编程语言 >C++中对象的初始化和清理

C++中对象的初始化和清理

时间:2024-12-05 20:28:13浏览次数:5  
标签:无参 初始化 调用 函数 int 清理 C++ include 构造函数

一、.初始化:

对象的初始化使用构造函数

构造函数

构造函数:主要作用在于创造对时为对象的成员属性(成员变量)赋值,构造函数由编译器自动调用,无需手动调用

语法:类名(){}

1.构造函数没有返回值,函数名前也不用写void

2.函数名与类名相同

3.构造函数可以有参数,因此可以发生重载

4.程序在调用对象的时候会自动调用构造函数,无需手动调用,而且只会调用一次

5.当已经提供了有参构造时,程序不会提供无参构造(若此时调用无参构造,程序报错,须程序员手动提供无参构造)

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class A {
	int* p;
public:
	A()//构造函数,函数名与类名相同,没有返回值,函数名前不用写void,
		//如果没有实现构造函数编译器会提供默认的构造函数
	{
		cout << "默认构造" << endl;
	}
	A(int n) {
		if (n != 0) {
			p = new int[n];
			cout << "使用构造函数在堆区申请了n个int类型的变量" << endl;
 }
	}
};
int main() {
	A p;//输出:默认构造。在创建对象时编译器会帮我们自动调用构造函数,无需手动调用
	A p1(2);//输出:使用构造函数在堆区申请了n个int类型的变量。调用有参构造创造对象
	A p2();//输出:  编译器会把它认为是函数声明,A是返回值类型,p2是函数名,()是函数参数
	return 0;
}

构造函数的分类及调用:

分类:

1.按照参数分:有参构造和无参构造

2.按照类型分:普通构造和拷贝构造

调用方式:

1.括号发

2.显示法

3.隐式转换法

#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;
class A {
	int* p;
public:
	A()
	{
		cout << "默认构造" << endl;
	}
	A(int n) {
 cout << "调用有参构造" << endl;
	if (n > 0)p = new int(n);//p指向一块int类型的内存,值为n
	else{
	p = NULL;
	cout << "数据不准确" << endl;
 }
	}
	void a(){
	 if (p) {
		cout << "打印p指向堆区内存值:" << *p << endl;
	 }
}
};
int main() {
	A t(1);//输出:调用有参构造。括号法相当于A t=A(1);
	A t1 = A(3);//输出:调用有参构造。显示法
	A t2 = 3;//输出:调用有参构造。隐式转换法,在此处会调用参数为int类型的构造函数,将3转换为A类型对象
	A t3();//不是括号发,编译器会把它认为是函数声明,A是返回值类型.t3是函数名,()是函数参数
	A t4;//输出:默认构造。调用无参构造
	return 0;
}

构造函数的调用规则

在默认情况下,C++至少会给一个类添加3个函数:

1.默认构造函数(无参,函数体为空)

2.默认析构函数(无参,函数体为空)

3.默认拷贝构造函数,对属性进行值拷贝。(简单的赋值)

构造函数调用规则:

1.如果用户定义有参构造,C++不再提供默认的无参构造,但会提供默认的拷贝构造

2.如果用户定义了拷贝构造,C++不再提供其他的任何构造函数(无参、有参、默认拷贝构造)

#include<iostream>
#include<vector>
using namespace std;
class Person {
	
public:
	int n;
	Person() {
		cout << "无参构造" << endl;
	}
	Person(int n) {
		this->n = n;
		cout << " 有参构造" << endl;
	}
	Person(const Person& other) {
		this->n = other.n;
		cout << " 拷贝构造" << endl;
	}
	~Person() {
		cout << "析构函数" << endl;
	}
};
void test1() {
	Person p1(18);
	
	Person p2(p1);//如果不写拷贝构造,编译器会自动添加默认的拷贝构造(浅拷贝)
	//此处的拷贝构造,相当于使用一个已经创建完毕的对象(已经存在的对象)初始化一个新对象
	cout << "p2为:" << p2.n << endl;
}
void test2() {
	//如果用户提供有参构造,编译器不会提供默认的无参构造,但会提供默认的拷贝构造
	Person p1;//此时如果用户没有提供默认构造,编译器会报错
	Person p2(10);//调用用户提供的有参构造
	Person p3(p2);//调用拷贝构造,如果此时用户没有提供拷贝构造,编译器会提供默认的拷贝构造
	
	//如果用户提供了拷贝构造,编译器不会提供其他任何的拷贝构造
	Person p4;//此时如果用户没有提供默认构造,编译器会报错
	Person p5(10);//调用用户提供的有参构造,此时如果用户没有提供有参构造,编译器会报错
	Person p6(p5);//调用拷贝构造
}
int main() {
	test1();
	return 0;
}

二、对象的清理

对象需要调用析构函数来清理

析构函数

主要作用在于对象销毁前系统自动调用,执行一些清理工作

语法:~( )类名{ }

1.析构函数没有返回值,也不用写void

2.函数名跟类名相同,在名称前加符号:~

3.析构函数不可以有参数,因此不能发生重载

4.程序在对象销毁前会自动调用析构,无需手动调用,而且只会调用一次

#include<iostream>
using namespace std;
class Pointer {
	int* p=NULL;
public:
	Pointer() {
		cout << "默认构造" << endl;
	}
	Pointer(int n) {
		cout << "调用有参构造" << endl;
		if (n > 0) {
			p = new int[n];//使用构造函数在堆区申请了n个int类型的变量
		}
	}
	//析构函数用于帮助我们释放指针变量指向的堆区内存
	~Pointer() {
		if (p)delete[]p;
	}
};
void test() {
	Pointer p(2);
}
int main() {
	test();
	return 0;
}

标签:无参,初始化,调用,函数,int,清理,C++,include,构造函数
From: https://blog.csdn.net/2401_88249494/article/details/144195919

相关文章

  • C++学习日记---第18天(5k字 重载运算符快速通关)
    (本文包含了从基础到中等的运算符重载内容,以及一些在编写代码时可能遇到的问题) 笔记复习1.运算符重载以代码实现一个类的两个对象相加为例#include<iostream>usingnamespacestd;classperson{ intm_deposit=1000; intincome=100;};intmain(){ person......
  • C++算法练习-day62——491.非递减子序列
    题目来源:.-力扣(LeetCode)题目思路分析这个问题要求找出数组 nums 中的所有非严格递增子序列,其中每个子序列至少包含两个元素。非严格递增子序列意味着子序列中的元素可以相等,但不允许递减。为了解决这个问题,可以使用回溯法。回溯法是一种通过探索所有可能的候选解来找出......
  • C++算法练习-day61——90.子集2
    题目来源:.-力扣(LeetCode)题目思路分析题目要求找出给定数组的所有子集(幂集),但数组可能包含重复元素,要求结果中的子集是唯一的(不包含重复的子集)。为了解决这个问题,我们可以先对数组进行排序,然后在回溯过程中跳过重复的元素,以确保生成的每个子集都是唯一的。代码:#include<v......
  • C++算法练习-day60——78.子集问题
    题目来源:.-力扣(LeetCode)题目思路分析题目要求找出给定数组的所有子集(幂集)。子集是指原数组中任意元素组合形成的数组,包括空集和原数组本身。这个问题可以通过回溯算法(Backtracking)来解决。回溯算法是一种通过探索所有可能的候选解来找出所有解的算法。对于子集问题,我们可以......
  • C++对象模型实践探索
    前言C++对象模型是个常见、且复杂的话题,本文基于ItaniumC++ABI通过程序实践介绍了几种简单C++继承场景下对象模型,尤其是存在虚函数的场景,并通过图的方式直观表达内存布局。本文展示的程序构建环境为Ubuntu,glibc2.24,gcc6.3.0。由于clang和gcc编译器都是基于ItaniumC++......
  • 【C++动态规划 BFS 博弈】3283. 吃掉所有兵需要的最多移动次数|2473
    本文涉及知识点C++动态规划C++BFS算法数学博弈LeetCode3283.吃掉所有兵需要的最多移动次数给你一个50x50的国际象棋棋盘,棋盘上有一个马和一些兵。给你两个整数kx和ky,其中(kx,ky)表示马所在的位置,同时还有一个二维数组positions,其中positions[i]=[x......
  • 一文教你用vite创建vue3项目初始化并添加router、axios、Pinia保姆级教程
    文章目录一、什么是vite二、什么是vue3三、什么是router四、什么是axios五、什么是pinia六、详细教程1.查看nodejs版本2.使用vite最新版3.配置@指代src目录(可选)4.安装router5.引入axios6.引入pinia一、什么是viteVite是新一代的前端构建工具,在尤雨溪开发Vue3.0的......
  • 保姆级教程用vite创建vue3项目并初始化添加PrimeVue UI踩坑实录
    文章目录一、什么是PrimeVue二、详细教程1.添加PrimeVue2.配置main.js3.添加自动引入4.配置vite.config.js5.创建测试页面一、什么是PrimeVuePrimeVue是一个用于Vue.js3.x开发的一款高质量、广受欢迎的WebUI组件库。官网地址:https://primevue.org/二......
  • C++(fprintf())
    目录1.函数定义2.常见格式说明符3.示例代码4.适用场景fprintf()是C和C++中用于格式化输出到文件的标准库函数。它的功能类似于printf(),但与printf()不同的是,fprintf()将格式化后的数据输出到指定的文件,而不是标准输出流(通常是屏幕)。1.函数定义intfprintf(FILE......
  • (2024最新毕设合集)基于SSM的河北省博物馆管理系统-02350|可做计算机毕业设计JAVA、PHP
    目 录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2 河北省博物馆管理系统系统分析2.1可行性分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3操作可行性分析2.2系统功能分析2.2.1功能性分析2.2.2非功能性分析......