您现在的位置是:群英 > 开发技术 > 编程语言
c语言中类和对象的含义是什么,怎么理解
Admin发表于 2022-05-06 17:55:552505 次浏览
在实际案例的操作过程中,我们可能会遇到“c语言中类和对象的含义是什么,怎么理解”这样的问题,那么我们该如何处理和解决这样的情况呢?这篇小编就给大家总结了一些方法,具有一定的借鉴价值,希望对大家有所帮助,接下来就让小编带领大家一起了解看看吧。

目录
  • 一.初步认识面向过程和面向对象
  • 二.类的引入
  • 三.类的定义
    • 1.定义和声明全部放在类体中,需要注意的是:
    • 2.声明与定义分离
  • 四.类的访问限定符及封装
    • 1.访问限定符
    • 2.封装
  • 五.类的作用域
    • 六.类的实例化
      • 七.类对象模型
        • 1.计算类对象的大小
        • 2.类对象的存储方式
      • 八.this指针
        • 1.this指针的引出
        • 2.this指针的特性
      • 总结

        一.初步认识面向过程和面向对象

        面向过程,关注的是怎么去做,比如在外卖系统中,强调点餐,做餐,送餐等一系列动作的方法,反映到语言中是函数方法的实现;而面向对象,更关注的是谁去做,比如在外卖系统中,强调的是商家,买家和送货员之间的交互,反映到语言中则是对象的实现。

        C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

        C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

        这里C++由于兼容C语言,因此既是面向过程,又是面向对象的,但是C++更关注的是对象,所以说C++是基于面向对象的。

        二.类的引入

        在C语言中,结构体只能定义变量,而在C++中,结构体升级为类,既可以定义变量,也可以定义函数:

        struct Book
        {
        	void SetInfo(const char* name, const char* writer, double price)//建立书本信息
        	{
        		strcpy(_name, name);
        		strcpy(_writer, writer);
        		_price = price;
        	}
        	void PrintInfo()//打印书本信息
        	{
        		cout << _name << endl;
        		cout << _writer << endl;
        		cout << _price << endl;
        	}
        	char _name[20];
        	char _writer[20];
        	double _price;
        };
        int main()
        {
        	Book b1;
        	Book b2;
        	b1.SetInfo("老人与海", "海明威", 12.54);
        	b2.SetInfo("骆驼祥子", "老舍", 14.88);
        	b1.PrintInfo();
        	cout << endl;
        	b2.PrintInfo();
        	return 0;
        }
        

        上面的结构体struct即为一个类,{}则形成了一个类域,{}中的内容为结构体Book的成员,既有成员变量,又有成员函数。在C++中,类通常用class这个关键字来表示。那么struct和class二者之间有什么区别呢?接下来我们就来介绍类。

        三.类的定义

        class className
        {
         // 类体:由成员函数和成员变量组成
        }; // 一定要注意后面的分号
        

        class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号。

        类中的元素称为类的成员:类中的数据称为类的属性或者成员变量; 类中的函数称为类的方法或者成员函数。

        类的两种定义方式:

        1.定义和声明全部放在类体中,需要注意的是:

        成员函数被定义在类体中,编译器会默认将其当作内联函数,其效用等同于函数前加上inline关键字,若不知道何为内联函数,可以参考之前文章中关于内联函数的介绍。

        C++入门


        2.声明与定义分离

        声明放在头文件中,而定义放在源文件中。

        通常情况下,为了代码的规范性,更倾向于采用第二种方法来实现类,并且代码较短的成员函数直接定义在类体中,而代码较长的函数定义在类体外。

        需要注意的是,类中的成员变量均为声明,它们在实例化之前都未被分配空间,不能称作为定义。

        四.类的访问限定符及封装

        1.访问限定符

        在之前我们讨论到class和struct之间有什么区别,那么这里我们将会介绍,首先,我们来了解以下类的访问限定符及封装。
        C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。


        访问限定符的说明:

        1.public修饰的成员在类外可以直接被访问

        2.protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)

        3.访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

        4.在没有访问限定符的情况下,class的默认访问权限为private,struct为public(因为struct要兼容C)

        注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别。

        由上面的说明我们就可以知道struct和class这两个关键字之间的区别在哪里了:实际使用过程中,struct和class定义类时并无区别,只是在二者均没有访问限定符的时候,struct默认的访问权限为public,而class默认的访问权限为private。

        2.封装

        我们知道面向对象有三大特性:封装,继承,多态。在类和对象阶段,我们研究类的封装特性。

        首先,封装指的是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

        其次,从本质上来说,封装是一种管理:举个例子,景区如果不加管理的话,那么景区的东西很可能会被不守规章制度的人破坏,这就好比C语言中为被封装的代码随时可能被修改,有时导致出现很大的错误;那么为了加强管理,保护景区,就需要设立景点售票口,同时安装监控和保安来保证景区不被破坏。

        类也是如此,对于我们不想被随意修改的成员变量,我们用private表示其为私有,而为了使用者能够合理调用,我们将使用方法封装成一个个的接口即成员函数用public表示其为公用,至此我们将成员封装起来,同时开放一些公有的成员函数对成员合理的访问。所以封装本质是一种管理,使用封装可以是代码更加安全。

        五.类的作用域

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

        比如,在上面介绍类的第二种实现方式中的代码,在Book.cpp中定义函数ShowInfo时就是指定其为类域Book中的成员函数。

        //Book.h
        class Book//书
        {
        public:
        	void ShowInfo();//展示书的信息
        private:
        	char* _name;//书名
        	char* _writer;//作者
        	double _price;//价格
        //Book.cpp
        #include "test.h"
        void Book::ShowInfo()
        {
        	cout << _name << " " << _writer << " " << _price << endl;
        }
        };
        

        六.类的实例化

        用类类型创建对象的过程,称为类的实例化

        1.类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它

        2.一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量

        3.打个比方,类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间


        七.类对象模型

        1.计算类对象的大小

        类包含了成员变量和成员函数,那么类的大小应该如何计算呢?首先我们来看看下面这个代码的结果是什么:

        class Book
        {
        public:
        	void ShowInfo(){}
        private:
        	char* _name;
        	char* _writer;
        	double _price;
        };
        int main()
        {
        	cout << sizeof(Book) << endl;
        	return 0;
        }
        


        可以看到,类Book的大小为16,那么这个16是怎么求出来的呢?

        2.类对象的存储方式

        我们再来看一个代码:

        class C1//类中既有成员变量,又有成员函数
        {
        public:
        	void fun();
        private:
        	int _a;
        };
        class C2//类中只有成员函数
        {
        public:
        	void fun();
        };
        class C3//类中什么都没有,即空类
        {
        };
        int main()
        {
        	cout << "C1:" << sizeof(C1) << endl;
        	cout << "C2:" << sizeof(C2) << endl;
        	cout << "C3:" << sizeof(C3) << endl;
        	return 0;
        }
        

        它的结果是:


        可以看到C1的大小为成员变量_a的大小,C2和C3的大小均为1,说明类的大小并不包括成员函数的大小,实际上如果类实例化时也会给成员函数开辟一块空间,那么当一个类创建多个对象时,每个对象中都会保存一份成员函数的代码,相同代码保存多次,浪费空间。

        既然成员函数不在类的大小计算范围内,那么为什么空类的大小为1呢?这是因为一个类创建的时候需要开辟一块空间来占位,因此内存需要开辟一个字节,这个字节的空间是没有意义的,其不存储任何有效数据,但是其标识了空类的存在。


        结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。

        八.this指针

        1.this指针的引出

        不知道你是否注意到,在C和C++实现栈的代码中,二者的函数参数有些许不同


        可以看到,C++的函数参数比起C语言实现的函数都少了一个参数,那么问题来了,在下面代码中s1和s2都调用Init函数时,编译器是怎么区别是哪个变量调用的呢?这就是我们即将要介绍的this指针所起到的作用了。

        int main()
        {
        	cpp::Stack s1;
        	cpp::Stack s2;
        	s1.Init();
        	s2.Init();
        	s1.Push(1);
        	return 0;
        }
        

        实际上,C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有成员变量的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。


        根据调试窗口可以看到this指针就是s1的地址,通过this指针可以访问s1。

        2.this指针的特性

        1.this指针的类型:类类型* const,比如上面代码中的this指针类型为Stack*

        2.只能在“成员函数”的内部使用,this作为一个关键字不能拿它去当作变量的名字,其使用时可以显式的使用,比如:

        		void Init() 
        		{
        			this->_a = (int*)malloc(sizeof(int) * 4);
        			this->_top = 0;
        			this->_capacity = 4;
        		}
        

        3.this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。又因为this指针为形参,而形参和函数中的局部变量是存储在函数栈帧中的,因此this指针可以认为是存储在栈中的。

        4.this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递.


        我们最后再来看一个问题:this指针可以为空吗?

        我们还是通过一个代码来看:

        class A
        {
        public:
        	void Show()
        	{
        		cout << "Show()" << endl;
        	}
        	void Print()
        	{
        		cout << _a << endl;
        	}
        private:
        	int _a;
        };
        int main()
        {
        	A* p = nullptr;
        	p->Show();
        	p->Print();
        	return 0;
        }
        

        那么p->Show(); p->Print();这两句代码能否运行成功呢?



        可以看到第一句代码运行成功了,而第二句代码运行崩溃了。

        这是因为成员函数的地址并不存在于对象中,而是存在于公共代码段;而上面的代码中调用函数时将p传给了隐含的this指针,并不会去访问p所指向的空间,就不存在空指针的解引用,因此程序可以并编译成功。而调用Show函数也没有对this指针解引用,因此程序运行成功了;调用Print函数则会对this指针解引用,故程序崩溃了。

        结论:对于调用不会对this指针解引用的函数,this指针可以为空;而对于调用会对this指针解引用的函数,this指针不能为空。

        总结



        关于“c语言中类和对象的含义是什么,怎么理解”的内容就介绍到这,感谢各位的阅读,相信大家对c语言中类和对象的含义是什么,怎么理解已经有了进一步的了解。大家如果还想学习更多知识,欢迎关注群英网络,小编将为大家输出更多高质量的实用文章!

        免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

        相关信息推荐
        2022-05-06 18:09:24 
        摘要:微信小程序如何封装原生请求?如何调用接口?下面本篇文章给大家介绍一下原生微信小程序封装请求,并优雅调用接口的方法,希望对大家有所帮助!
        2022-09-08 18:02:18 
        摘要:es6中static修饰符是修饰成员变量和成员方法的意思,static是静态的意思,也即定义静态方法;static修饰成员变量表示该成员变量在内存中只存储一份,可以被共享访问和修改,类通过static定义静态方法。
        2022-11-30 18:00:41 
        摘要:两种增加方法:1、直接利用strtotime()函数计算时间间隔,可将间隔后的日期以UNIX时间戳的格式返回,语法“strtotime("+1 day")”;2、利用time()函数计算当前时间戳,并在当前时间戳的基础上加上一天的秒数即可,语法“time()+(1 * 24 * 3600)”。
        云活动
        推荐内容
        热门关键词
        热门信息
        群英网络助力开启安全的云计算之旅
        立即注册,领取新人大礼包
        • 联系我们
        • 24小时售后:4006784567
        • 24小时TEL :0668-2555666
        • 售前咨询TEL:400-678-4567

        • 官方微信

          官方微信
        Copyright  ©  QY  Network  Company  Ltd. All  Rights  Reserved. 2003-2019  群英网络  版权所有   茂名市群英网络有限公司
        增值电信经营许可证 : B1.B2-20140078   粤ICP备09006778号
        免费拨打  400-678-4567
        免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
        微信公众号
        返回顶部
        返回顶部 返回顶部