C++(类和对象)

本文详细介绍了C++中的类和对象概念,包括成员的访问级别、构造函数(无参、有参及拷贝构造)、析构函数的作用,以及深拷贝与浅拷贝的区别。还讨论了this指针的用法和空指针的注意事项,以及const修饰的成员函数特性。
摘要由CSDN通过智能技术生成

4、类和对象

1)private、public

在这里插入图片描述
除了s1.setName(),还可以通过行为给属性赋值。
类中的属性和方法叫成员。
在这里插入图片描述
在这里插入图片描述

2)成员属性设置为私有

在这里插入图片描述
也就是通过public对private的数据可读可写

class Person {
public:
	//姓名设置可读可写
	void setName(string name) 
	{
	m_Name = name;
	} 
	string getName()
	{
	return m_Name;
	} 
//获取年龄
	int getAge() 
	{
	return m_Age;
	} 
//设置年龄
	void setAge(int age) 
 {
	if (age < 0 || age > 150) {
	cout << "你个老妖精!" << endl;
	return;
	} 
	m_Age = age;
 } 
//情人设置为只写
void setLover(string lover)
	{
	m_Lover = lover;
	}
private:
	string m_Name; //可读可写 姓名
	int m_Age; //只读 年龄
	string m_Lover; //只写 情人
};
int main() {
	Person p;
	//姓名设置
	p.setName("张三");
	cout << "姓名: " << p.getName() << endl;
	//年龄设置
	p.setAge(50);
	cout << "年龄: " << p.getAge() << endl;
	//情人设置
	p.setLover("苍井");
	//cout << "情人: " << p.m_Lover << endl; //只写属性,不可以读取
	system("pause");
	return 0}

写一个类思考问题:
数据有哪些
这些数据做什么
数据放在private,行为放在public
通过public为private赋值,并操作。

2)构造和析构
生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用时候也会删除一些自己信息数据
保证安全
C++中的面向对象来源于生活,每个对象也都会有初始设置以及 对象销毁前的清理数据的设置。

构造函数语法: 类名(){}

  1. 构造函数,没有返回值也不写void
  2. 函数名称与类名相同
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
    析构函数语法: ~类名(){}
  5. 析构函数,没有返回值也不写void
  6. 函数名称与类名相同,在名称前加上符号 ~
  7. 析构函数不可以有参数,因此不可以发生重载
  8. 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
class Person
{ 
    
public:
    //构造函数
    Person()
    {
    cout << "Person的构造函数调用" << endl;
    } 
//析构函数
    ~Person()
    {
    cout << "Person的析构函数调用" << endl;
    }
    };
    void test01()
    {
    Person p;  //这儿是创建对象,不是调用函数,但是还是会自动调用构造函数
    } 
int main() 
{
    test01();
    system("pause");
    return 0;
}

void test01()
{
Person p; //这儿是创建对象,不是调用函数,但是还是会自动调用构造函数
}
也就是创建对象时,编译器自动调用构造函数

int main() 
{
    //test01();
    Person p;  //只有构造,没有析构,继续执行到 system("pause");了,看不见析构,但是有!test是等test函数完成才析构,那是可以的
    system("pause");
    return 0;
}

3)构造函数分类

两种分类方式:
按参数分为: 有参构造和无参构造
按类型分为: 普通构造和拷贝构造
三种调用方式:
括号法
显示法
隐式转换法
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
解释:
在这里插入图片描述
拷贝构造函数,先传进来一个人Person p,假如这个叫张三,把身高体重给他。现在李四要拷贝它,那么张三要不变,所以要加const Person p,且用引用方式传递。

/
/有参构造函数
Person(int a) {
age = a;
cout << "有参构造函数!" << endl;
} /
/拷贝构造函数
Person(const Person& p) {
age = p.age;
cout << "拷贝构造函数!" << endl;
}

构造函数就可以将传进来的a赋给age了,且拷贝函数用age = p.age;表示

调用:

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

25 拷贝函数怎么调用

C++中拷贝构造函数调用时机通常有三种情况
使用一个已经创建完毕的对象来初始化一个新对象
值传递的方式给函数参数传值
以值方式返回局部对象
在这里插入图片描述
值传递只会影响临时副本,不会影响原来的

构造函数调用规则

![!](https://img-blog.csdnimg.cn/direct/3cc60e0161a74f43b8bc8e2515ebfc88.png)](https://img-
没写拷贝函数,也会进行值拷贝。

//拷贝构造函数
Person(const Person& p) {
age = p.age;
cout << "拷贝构造函数!" << endl;
}
void test01()
{
Person p1(18);
//如果不写拷贝构造,编译器会自动添加拷贝构造,并且做浅拷贝操作
Person p2(p1);
cout << "p2的年龄为: " << p2.age << endl;
}

即提供有参构,编译器不提供无参构。但提供下边的拷贝构造。(默认的)
提供拷贝,有无参构造都不提供

27 深拷贝和浅拷贝

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
int *mHeight = new int(height) ,是存在栈区,栈区先进后厨
在这里插入图片描述
浅拷贝是完全复制,而p2先释放,因此p1再去释放,就没了。产生重复释放,解决办法是深拷贝,在堆区重新申请空间。
在这里插入图片描述

在这里插入图片描述

28 初始化列表

在这里插入图片描述
在这里插入图片描述
上面写死了,下面来
在这里插入图片描述
传递逻辑
在这里插入图片描述

29 类对象作为类成员

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解释如下:
类中对象有Phone m_Phone;那么它是先构造Person还是Phone呢?
/当类中成员是其他类对象时,我们称该成员为 对象成员
//构造的顺序是 :先调用对象成员的构造,再调用本类构造
//析构顺序与构造相反
在这里插入图片描述
人现有胳膊腿,才有完成的人,phone就相当于胳膊腿

30&31

在这里插入图片描述

32 成员变量和成员函数分开存储

在这里插入图片描述
为1,因为要为对象创建一个空间
在这里插入图片描述
在这里插入图片描述
int占4个,静态变量、非静态函数不属于成员变量,不占字节。即只有非静态属于

33 this指针

有很多对象,怎么区分是p1,还是p2,p3调用这个成员函数呢
作用:
1、解决名字冲突
2、返回对象本身用this
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
并不是18,因为编译器认为person类中三个age是同一份,与成员属性age不是一回事。解决办法
1)成员变量改个名
int m_age
2)this
构造函数内的
this->age = age
this指针指向被调用的成员函数所属的对象
被调用的成员函数所属的对象:是p1(对象时p1)
返回对象用
this
在这里插入图片描述
不用return *this;p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);会错
用了每次都是返回p2,因此是可以的继续用
在这里插入图片描述
在这里插入图片描述

值返回就是20,因为会是拎一个对象了。拷贝函数

在这里插入图片描述
34 空指针
在这里插入图片描述
第一个正确,第二个错误,其实age前面默认加了个this,即this->m_age,表当前对象属性
但是当前对象为空,你还去访问它,所以错。
加个判断
在这里插入图片描述
35 const修饰成员函数
在这里插入图片描述
常函数
在这里插入图片描述

this是指向p的,本质是指针常量,int *const p格式,/ p(this)是一个指针常量,它的值(地址)是固定的,不能被改变。
this = null是错,this->m_a=100是对
函数后面加个const,那么就相当于const Person *const this;,指针指向的值都不可以修改了。
this->ma=100;=null都是错
加上mutable就可以修改了
在这里插入图片描述
常对象
在对象前加上const
在这里插入图片描述

在这里插入图片描述
func为正常函数,不能调用,常对象只能调用常函数

  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值