欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 【C++】类和对象【上】

【C++】类和对象【上】

2025/4/26 12:13:12 来源:https://blog.csdn.net/2401_86785052/article/details/147513547  浏览:    关键词:【C++】类和对象【上】

目录

  • 一、类和对象
    • 1.1 类的定义
    • 1.2 访问限定符
    • 1.3 类域
    • 2.1 实例化概念
    • 2.2 对象的大小
    • 3、`this`指针
  • 二、小测验
    • 1、
    • 2、

在这里插入图片描述

个人主页<—请点击
C++专栏<—请点击

一、类和对象

C++中一共有四个域,分别是全局域、局部域、命名空间域、类域。前三个域我们已经了解了,接下来,让我们一起了解类域。

1.1 类的定义

class为定义类的关键字{}中为类的主体,注意类定义结束时后面分号不能省
略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量;类中的函数称为类的方法或者成员函数。

为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前面或者后面加_ 或者 m开头,注意C++中这个并不是强制的,只是⼀些惯例。

C++struct也可以定义类,C++兼容Cstruct的⽤法,同时struct升级成了类,明显的变化struct可以定义函数,⼀般情况下我们还是推荐用class定义类。

定义在类里面的成员函数默认为inline

假设此时我们要定义一个栈类:

class Stack
{
public:// 成员函数void Init(int n = 4){array = (int*)malloc(sizeof(int) * n);if (nullptr == array){perror("malloc申请空间失败");return;}capacity = n;top = 0;}void Destroy(){free(array);array = nullptr;top = capacity = 0;}void Push(int x){// ...扩容array[top++] = x;}int Top(){assert(top > 0);return array[top - 1];}private:// 成员变量int* array;size_t capacity;size_t top;
};

Stack是类的名字。其中还出现了publicprivate这是类中的访问限定符,我们接下来讲。

1.2 访问限定符

C++的⼀种实现封装的方式,用类将对象的属性方法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。

访问限定符共有三种public、private、protected

public修饰的成员在类外可以直接被访问protectedprivate修饰的成员在类外不能直接被访问

访问权限作用域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为止,如果后面没有访问限定符,作用域就到 },即类结束为止。

class定义成员没有被访问限定符修饰时默认为privatestruct默认为public。⼀般成员变量都会被限制为private/protected,需要给别人使用的成员函数会放为public

1.3 类域

定义了⼀个新的作用域类的所有成员都在类的作用域中,在类体外定义成员时,需要使用 ::作用域操作符指明成员属于哪个类域

2.1 实例化概念

类型在物理内存中创建对象的过程,称为类实例化出对象

是对象进行的⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间。就像图纸一样,图纸没有空间,只有按照图纸建成房子才有空间,才能使用。
在这里插入图片描述
此时我要创建出一个日期类。

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:// 声明int _year;   int _month;int _day;
};

Date实例化出对象d1d2:

Date d1;
Date d2;

2.2 对象的大小

类实例化出的每个对象,都有独立的数据空间,所以对象中肯定包含成员变量但对象中是不包含成员函数的。假设我定义100个对象,那它们每个对象中都储存成员函数太浪费空间了,反正最后调用的成员函数都一样,所以这些成员函数会储存在一块公共代码区
在这里插入图片描述
对象中只存储成员变量C++规定类实例化的对象也要符合内存对齐的规则。内存对齐可以提高读取数据的效率,以空间换时间。相关内存对齐规则可以查看—>内存对齐博客

计算⼀下A/B/C实例化的对象的大小:

#include<iostream>
using namespace std;class A
{
public:void Print(){cout << _ch << endl;}
private:char _ch;int _i;
};
class B
{
public:void Print(){//...}
};
class C
{
};
int main()
{A a;B b;C c;cout << sizeof(a) << endl;cout << sizeof(b) << endl;cout << sizeof(c) << endl;return 0;
}

在这里插入图片描述
bc没有成员变量,那它们大小不应该是0吗?但是如果是0就不能证明他们存在了,所以这里给1字节,是为了占位标识对象存在

3、this指针

我们在上面实现了日期类,我们来使用一下吧。

class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:// 声明int _year;   int _month;int _day;
};
int main()
{Date d1;Date d2;d1.Init(2025, 4, 25);d2.Init(2025, 4, 26);d1.Print();d2.Print();return 0;
}

运行结果:
在这里插入图片描述
这个结果和我们预期的一样,但好像有一个奇怪🧐的地方,前面我们讲过成员函数储存在一块公共代码区,并且我们调用Print函数的时候没有传参数,那为什么打印出来结果不同呢? 不应该是相同的吗?它是怎么分清谁是d1,谁是d2的?

其实C++使用了一个隐含this指针解决了这里的问题。编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。所以函数Print的真实原型为:void Print(const Date* this)

类的成员函数中访问成员变量,本质都是通过this指针访问的。C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针

所以我们可以直接显示使用来证明它存在:
在这里插入图片描述
在这里插入图片描述

二、小测验

1、

下面程序编译运行结果是()
A、正常运行 B、编译错误 C、运行崩溃

#include<iostream>
using namespace std;class A
{
public:void Print(){cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

答案A、正常运行
p->Print;这行代码没有涉及到空指针的解引用,因为Print函数没有存储在p中所以不需要解引用p,这行代码本质可以转化为call Print的地址p在这里有两个作用,第一个作用是告诉编译器到A类中去寻找Print的地址,第二个作用是当地址传给this指针,此时this就是空指针,但Print中不涉及this指针的解引用,所以可以正常运行
在这里插入图片描述

2、

下面程序编译运行结果是()
A、正常运行 B、编译错误 C、运行崩溃

#include<iostream>
using namespace std;class A
{
public:void Print(){cout << "A::Print()" << endl;cout << _a << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

答案:C、运行崩溃
cout << _a << endl;本质是cout << this->_a << endl;this此时是空指针,涉及到了空指针的解引用,所以会运行崩溃

总结:
以上就是本期博客分享的全部内容啦!如果觉得文章还不错的话可以三连支持一下,你的支持就是我前进最大的动力!
技术的探索永无止境! 道阻且长,行则将至!后续我会给大家带来更多优质博客内容,欢迎关注我的CSDN账号,我们一同成长!
(~ ̄▽ ̄)~

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词