欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

c++学习笔记2--类和对象基础

程序员文章站 2022-07-15 16:52:26
...

1 类和对象

C++面向对象的三大特性为:封装、继承、多态

1 封装

1.1 封装的意义
封装是C++面向对象三大特性之一

封装的意义一:

  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制
    类在设计时,可以把属性和行为放在不同的权限下,加以控制

封装意义二:

类在设计时,可以把属性和行为放在不同的权限下,加以控制

访问权限有三种:

  • 公共权限 public 类内可以访问 类外可以访问
  • 保护权限 protected 类内可以访问 类外不可以访问
  • 私有权限 private 类内可以访问 类外不可以访问

1.2 struct和class区别
在C++中 struct和class唯一的区别就在于 默认的访问权限不同

区别:

struct 默认权限为公共
class 默认权限为私有

1.2 对象的初始化和清理

1.2.1 对象的初始化和清理

编译器提供的构造函数和析构函数是空实现。

  • 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。
  • 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。
    构造函数语法:类名(){}

构造函数,没有返回值也不写void

  • 函数名称与类名相同
    构造函数可以有参数,因此可以发生重载

  • 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
    析构函数语法: ~类名(){}

  • 析构函数,没有返回值也不写void
    函数名称与类名相同,在名称前加上符号 ~

  • 析构函数不可以有参数,因此不可以发生重载
    程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次

1.2.2 构造函数的分类及调用
两种分类方式:

​ - 按参数分为: 有参构造和无参构造

​ - 按类型分为: 普通构造和拷贝构造

三种调用方式:

​- 括号法

​- 显示法

  • 隐式转换法
#include<bits/stdc++.h>
using namespace std;
//1、构造函数分类
// 按照参数分类分为 有参和无参构造   无参又称为默认构造函数
// 按照类型分类分为 普通构造和拷贝构造

class Person {
public:
	//无参(默认)构造函数
	Person() {
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int a) {
		age = a;
		cout << "有参构造函数!" << endl;
	}
	//拷贝构造函数
	Person(const Person& p) {
		age = p.age;
		cout << "拷贝构造函数!" << endl;
	}
	//析构函数
	~Person() {
		cout << "析构函数!" << endl;
	}
public:
	int age;
};

//2、构造函数的调用
//调用无参构造函数
void test01() {
	Person p; //调用无参构造函数
}

//调用有参的构造函数
void test02() {

	//2.1  括号法,常用
	Person p1(10);
	//注意1:调用无参构造函数不能加括号,如果加了编译器认为这是一个函数声明
	//Person p2();

	//2.2 显式法
	Person p2 = Person(10); 
	Person p3 = Person(p2);
	//Person(10)单独写就是匿名对象  当前行结束之后,马上析构

	//2.3 隐式转换法
	Person p4 = 10; // Person p4 = Person(10); 
	//Person p5 = p4; // Person p5 = Person(p4); 

	//注意2:不能利用 拷贝构造函数 初始化匿名对象 编译器认为是对象声明
	Person p5(p4);
}

int main() {

	//test01();
	test02();

	system("pause");

	return 0;
}

1.2.3 构造函数调用规则
默认情况下,c++编译器至少给一个类添加3个函数

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

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

3.默认拷贝构造函数,对属性进行值拷贝

构造函数调用规则如下:

如果用户定义有参构造函数,c++不在提供默认无参构造,但是会提供默认拷贝构造

如果用户定义拷贝构造函数,c++不会再提供其他构造函数

#include<bits/stdc++.h>
using namespace std;
//1、构造函数分类
// 按照参数分类分为 有参和无参构造   无参又称为默认构造函数
// 按照类型分类分为 普通构造和拷贝构造

class Person {
public:
	//无参(默认)构造函数
	Person() {
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int a) {
		age = a;
		cout << "有参构造函数!" << endl;
	}
	~Person() {
		cout << "析构函数!" << endl;
	}
public:
	int age;
};
int main(){
    Person p1=10;
    Person p2(p1);
    cout<<p2.age;
} 

1.2.4 深拷贝与浅拷贝
深浅拷贝是面试经典问题,也是常见的一个坑

浅拷贝:简单的赋值拷贝操作

深拷贝:在堆区重新申请空间,进行拷贝操作

class Person {
public:
	//无参(默认)构造函数
	Person() {
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int age ,int height) {
		
		cout << "有参构造函数!" << endl;

		m_age = age;
		m_height = new int(height);
		
	}
	//拷贝构造函数  
	Person(const Person& p) {
		cout << "拷贝构造函数!" << endl;
		//如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
		m_age = p.m_age;
		m_height = new int(*p.m_height);
		
	}

	//析构函数
	~Person() {
		cout << "析构函数!" << endl;
		if (m_height != NULL)
		{
			delete m_height;
		}
	}
public:
	int m_age;
	int* m_height;
};

void test01()
{
	Person p1(18, 180);

	Person p2(p1);

	cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;

	cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

1.2.5 静态成员

静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

静态成员分为:

  • 静态成员变量
    所有对象共享同一份数据
    在编译阶段分配内存
    类内声明,类外初始化
  • 静态成员函数
    所有对象共享同一个函数
    静态成员函数只能访问静态成员变量

示例1 :静态成员变量

class Person
{
	
public:

	static int m_A; //静态成员变量

	//静态成员变量特点:
	//1 在编译阶段分配内存
	//2 类内声明,类外初始化
	//3 所有对象共享同一份数据

private:
	static int m_B; //静态成员变量也是有访问权限的
};
int Person::m_A = 10;
int Person::m_B = 10;

void test01()
{
	//静态成员变量两种访问方式

	//1、通过对象
	Person p1;
	p1.m_A = 100;
	cout << "p1.m_A = " << p1.m_A << endl;

	Person p2;
	p2.m_A = 200;
	cout << "p1.m_A = " << p1.m_A << endl; //共享同一份数据
	cout << "p2.m_A = " << p2.m_A << endl;

	//2、通过类名
	cout << "m_A = " << Person::m_A << endl;


	//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
}

int main() {

	test01();

	system("pause");

	return 0;
}

2 C++对象模型和this指针