C++都有对象了,你还没有吗?

这篇具有很好参考价值的文章主要介绍了C++都有对象了,你还没有吗?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨
🐻推荐专栏1: 🍔🍟🌯C语言初阶
🐻推荐专栏2: 🍔🍟🌯C语言进阶
🔑个人信条: 🌵知行合一
🍉本篇简介:>:讲解C++中有关类和对象的初步了解.
金句分享:
✨应该有更好的方式开始新的一天,而不是千篇一律的每天醒来.✨

前言

一、面向过程与面向对象

C语言作为一种面向过程的编程语言,注重解决问题的过程和步骤,通过函数和控制流程的设计来组织程序。

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

现实实例:制作一个简单的三明治。
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

面向过程分析:(C语言)

  1. 收集所需材料和工具:面包、黄油、火腿、生菜、刀子、砧板等。
  2. 将切好的面包放在砧板上。
  3. 使用刀子涂抹黄油在面包片上。
  4. 在其中一片面包上放上火腿和生菜。
  5. 将另一片面包盖在火腿和生菜上,使之成为一个完整的三明治。
  6. 可选:将整个三明治切成两半或四等份。
  7. 完成。

面向对象分析:(C++)

  1. 定义一个"三明治"类,它具有属性(面包、黄油、火腿、生菜)和方法(涂抹黄油、放置火腿和生菜、组装成三明治)。
  2. 创建一个"三明治"对象。
  3. 调用对象的方法,按照特定的顺序执行:
  • 调用涂抹黄油的方法,在面包片上涂抹黄油。
  • 调用放置火腿和生菜的方法,在其中一片面包上放置火腿和生菜。
  • 调用组装成三明治的方法,将另一片面包盖在火腿和生菜上。
  1. 可选:调用切割的方法,将整个三明治切成两半或四等份。
  2. 完成。

面向过程分析中,我们按照步骤逐一执行操作,强调流程和步骤的线性顺序。

而在面向对象分析中,我们将问题抽象为一个对象,该对象具有属性和方法,通过调用对象的方法来实现功能,强调对象的行为和内部状态的封装。

总之面向对象以后,重点不再关注做事的具体过程,而是关注其中涉及哪些对象

二、类

2.1 类的介绍

还记得C语言阶段学习过的结构体吧?在结构体中我们可以定义各种类型的变量,但是我们不能在结构体中定义函数.

C语言中:
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构
同样一段代码在C++中,结构体内不仅可以定义变量,也可以定义函数。

C++中:
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构
为什么呢?因为C++中将结构体升级为了==“类”.在类==中是可以定义函数的,通常被称为成员函数.

C++中,class关键字用于定义一个类。类是一个用户定义的数据类型。
类体中内容称为类的成员:可以包含属性(成员变量)和操作/方法(成员函数)。

2.2 类的定义方式

使用class关键字可以创建一个新的类,并定义它的特征(如数据成员和成员函数)。类可以用于封装数据和行为,并提供对外部程序的接口。通过类的实例化,可以创建对象,并访问其成员变量和成员函数。在面向对象编程中,类是非常重要的一个概念,它使得程序更加模块化,易于维护和扩展。

(1)声明和定义全部放在类体中.

注意:成员函数如果在类中定义,编译器默认是按内联函数(inline)处理.(同样如果函数体过长也是不会产生内联的.)


#include <iostream>

using namespace std;//在工程代码中不建议展开可能会产生命名冲突

class Person {
public:
    // 构造函数(后面会讲,这里按普通成员函数理解)
    Person(char* n, int a) {
        name = n;
        age = a;
    }

    // 成员函数
    void introduce() {
        cout << "欢迎来到CSDN!\n我是" << name << ",我的年龄是" << age << "岁" << endl;
    }
private:
    //成员变量
    char* name;
    int age;
};

int main() {
    char name[] = "初阶牛";
    Person person(name, 18);
    person.introduce();

    return 0;
}

运行结果:

欢迎来到CSDN!
我是初阶牛,我的年龄是18

这个类的名字叫做 Person,它有两个私有成员变量:nameage

类还有一个公有的成员函数:introduceintroduce 函数用于打印出个人信息,即打印出对象的 nameage 属性。

main 函数中,我们创建了一个名为 personPerson 对象,并通过构造函数初始化了它的成员变量。然后我们调用了 introduce 函数来展示个人信息。

通过使用成员函数和成员变量,我们可以对对象进行操作和访问其属性,从而使类具有更多的功能和灵活性。请注意,在 C++ 中需要使用 iostream 库进行输入输出操作,并使用 main 函数创建类的对象并调用成员函数。

(2)类的声明和"成员函数"分离

即类声明放在.h文件中,成员函数定义放在.cpp文件中.

注意:成员函数名前需要加类名::
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

2.3 类的访问限定符

C++中,类的访问限定符(访问修饰符)用于控制类的成员对外部代码的可见性和访问权限。C++提供了三个主要的访问限定符:publicprivateprotected

  1. 公共访问(public):使用public关键字来指定。公共成员可以从任何地方访问,包括外部代码和其他类。公共成员在整个程序中可见。

  2. 私有访问(private):使用private关键字来指定。私有成员只能在声明它们的类内部访问。其他任何外部代码或其他类都无法直接访问私有成员,包括子类。

  3. 受保护访问(protected):使用protected关键字来指定。受保护成员只能在声明它们的类内部访问以及该类的子类中访问。外部代码无法直接访问受保护成员。

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

我们暂时这里将私有访问(private )和受保护访问(protected)看作相同的,后续再区分.

注意:

  1. C++中class(类)的默认访问级别是私有访问(private)。类的成员将默认为私有成员,只能在类内部访问。
  2. struct(结构体)为public(因为struct要兼容C语言),在C语言中,外部可以访问结构体中的成员变量.

访问限定符的选择取决于设计需求和封装原则。公共成员允许类的用户直接访问,而私有成员则隐藏了实现细节并提供了更好的封装。受保护成员专门用于派生类访问,并且在类外部不可见。

2.4 封装的介绍

封装的定义:(灰常重要)

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

封装本质上是一种管理,让用户更方便使用类。

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

在现实世界中,手机是一个复杂的设备,它包含了许多内部组件和功能,如屏幕、摄像头、声音、通信等。对于我们普通用户来讲,手机只需要提供给我们我们点击的屏幕,和手动控制开关机的按键就可以了,它内部具体是怎么实现功能的我们并不关心,如果让用户去关心CPU如何设计,主板上的线路如何布局,这显然是不合理的,手机的封装也就体现了管理,帮助用户更方便的使用手机

在C++语言中实现封装,可以通过类将数据以及操作数据的方法进行有机结合,通过访问权限来隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用。

三、“类” 与 “对象” 之间的关系

我们先看一下test2函数.

class Person {
public:
    //成员函数
    Person(char* n, int a);
    void introduce();

private:
    //私有成员变量
    char* name;
    int age;
public:
    float weight;
};

void test2()
{
    //报错
    Person.weight = 60.5;//报错,类只是声明,并没有申请空间,不能用于存放数据
    
    //正确写法
    char name[] = "初阶牛";
    Person cjn(name, 18);//通过类实例化出 cjn这个对象.
    cjn.introduce();
    cjn.weight = 60.5;//实例化出来的对象是有空间的,可以存储数据

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

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

有一个很形象的比喻,就好比是建筑的图纸,只是一些声明,并不没有去申请实际的空间,就好比图纸只是设计形状,并没有占有空间.不能存储数据,就类似于图纸不能住人.
通过类实例化出的对象后就分配的实际空间,对象可以用于存储数据,就像图纸设计出来房子后,房子里面就可以住人了.
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

3.1 类的大小计算

试着猜一下下面People类的大小.

#include <iostream>

using std::cout;
using std::cin;
using std::endl;

class People
{
public:
	void Print()
	{
		int a = 0;
		double b= 1.2;
		cout << _name << endl;
	}
private:
	char _name;
	int _age;
};

int main()
{
	cout << sizeof(People) << endl;
	return 0;
}

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构
运行结果:

8

解释:
为什么是8呢?因为类在计算大小时也要考虑内存对齐.
char _name占1个字节(偏移量为0),int _age占四个字节(4-7偏移量).共八个字节.
为什么不计算成员函数的大小呢?

那就要说到类的设计方式了,因为成员函数消耗的内存相对都比较大,而每个对象都是使用同一个成员函数,如果每个对象都给成员函数开辟空间,这就比较浪费了,所以C++中的类采用下图这种方式存储:
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构
将;类的成员函数放在公共代码段,需要使用的时候调用即可,对象之间公用同一个成员函数.这种设计方式有效的节省了类实例化出对象后的空间消耗.

那小伙伴掌握如何计算类的大小了吗?

不妨猜一下下面A类和B类的大小.

// 只有成员函数的类
class A {
public:
	void test() {}
};
//空类
class B

{};

int main()
{
	cout << sizeof(A) << endl;
	cout << sizeof(B) << endl;
	return 0;
}

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构
运行结果:

1
1

这是因为没有成员变量的类或者空类也是会在占用一个字节,因为需要占位,表示对象的存在.

3.2 this指针

#include <iostream>

using std::cout;
using std::cin;
using std::endl;


class Person {
public:
    //成员函数
    Person(char* n, int a)
    {
	    _name = n;
	    _age = a;
    }

    void introduce()
    {
        cout << _name << endl;
    }

private:
    //私有成员变量
    char* _name;
    int _age;
};

int main()
{
    char name1[] = "初阶牛";
    char name2[] = "CSDN";
    Person person1(name1, 18);
    Person person2(name2, 18);
    //这两个调用的是同一个函数吗?
    person1.introduce();
    person2.introduce();
	return 0;
}

运行结果:

初阶牛
CSDN

上面这段代码中这两个调用的是同一个函数吗?如果是同一个,为什么打印的结果却不一样?

    person1.introduce();
    person2.introduce();

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

没理解的看过来:
C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

其实就是编译器帮我们传了参,不需要用户进行手动传参.

结构体内存对齐复习:传送门

3.3 深入理解this指针

为了深入理解this指针,下面有两道题可以做一下:

第一题:this指针本身存储在哪里?

A. 栈区
B. 堆区
C. 对象中
D. 常量区

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构
答案:

栈区,因为this指针就是一个形参,只不过是被编译器默认传递,形参是存放在栈区的 函数栈帧建立时压栈,函数结束时,销毁.

第二题:下面这两段代码分别会出现什么情况?

//代码1:
class A
{
public:
	void Print()
	{
		cout << "HELLO CSDN" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}
// 代码2:
class A
{
public:
	void Print()
	{
		cout << _age << endl;
	}
private:
	int _age;
};
int main()
{
	A* p = nullptr;
	p->Print();
	return 0;
}

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

答案:
代码1:
正常运行,虽然this是空指针,但是并没有对this指针进行解引用,传递空指针是不会报错的.
代码2:
运行崩溃,对this空指针进行解引用,属于非法访问.
运行图如下:C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

四、C与C++对比

对比C语言,帮助更好的理解C++的封装特性.

C语言数据和方法是分离的,给予C程序员很大的操作空间.这样也就使得对C程序员的要求很高.太自由了!
比如:
对于一个用C语言实现的栈.很多数据在栈的外部可以被随意的修改和使用,这样就对程序员的要求极高.对于不规范的编程,(一会通过接口(函数),一会自己在外界直接访问)很容易造成混乱

C++程序员受封装的保护,对于栈中的很多操作只能通过调用对应的接口实现,更好的约束了程序员的操作规范

C实现栈:

//C语言版本
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <stdbool.h>

typedef int DataType;
typedef struct Stack
{
	DataType* array;
	int capacity;
	int size;
}Stack;
void StackInit(Stack* ps)
{
	assert(ps);
	ps->array = (DataType*)malloc(sizeof(DataType) * 3);
	if (NULL == ps->array)
	{
		assert(0);
		return;
	}
	ps->capacity = 3;
	ps->size = 0;
}
void StackDestroy(Stack* ps)
{
	assert(ps);
	if (ps->array)
	{
		free(ps->array);
		ps->array = NULL;
		ps->capacity = 0;
		ps->size = 0;
	}
}
void CheckCapacity(Stack* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity * 2;
		DataType* temp = (DataType*)realloc(ps->array,
			newcapacity * sizeof(DataType));
		if (temp == NULL)
		{
			perror("realloc申请空间失败!!!");
			return;
		}
		ps->array = temp;
		ps->capacity = newcapacity;
	}
}
void StackPush(Stack* ps, DataType data)
{
	assert(ps);
	CheckCapacity(ps);
	ps->array[ps->size] = data;
	ps->size++;
}
int StackEmpty(Stack* ps)
{
	assert(ps);
	return 0 == ps->size;
}
void StackPop(Stack* ps)
{
	if (StackEmpty(ps))
		return;
	ps->size--;
}
DataType StackTop(Stack* ps)
{
	assert(!StackEmpty(ps));
	return ps->array[ps->size - 1];
}
int StackSize(Stack* ps)
{
	assert(ps);
	return ps->size;
}
int main()
{
	Stack s;
	StackInit(&s);
	StackPush(&s, 1);
	StackPush(&s, 2);
	StackPush(&s, 3);
	StackPush(&s, 4);
	printf("%d\n", StackTop(&s));
	printf("%d\n", StackSize(&s));
	StackPop(&s);
	StackPop(&s);
	printf("%d\n", StackTop(&s));
	printf("%d\n", StackSize(&s));
	StackDestroy(&s);
	return 0;
}

C++实现栈:

typedef int DataType;
class Stack
{
public:
	void Init()
	{
		_array = (DataType*)malloc(sizeof(DataType) * 3);
		if (NULL == _array)
		{
			perror("malloc申请空间失败!!!");
			return;
		}
		_capacity = 3;
		_size = 0;
	}
	void Push(DataType data)
	{
		CheckCapacity();
		_array[_size] = data;
		_size++;
	}
	void Pop()
	{
		if (Empty())
			return;
		_size--;
	}
	DataType Top() { return _array[_size - 1]; }
	int Empty() { return 0 == _size; }
	int Size() { return _size; }
	void Destroy()
	{
		if (_array)
		{
			free(_array);
			_array = NULL;
			_capacity = 0;
			_size = 0;
		}
	}
private:
	void CheckCapacity()
	{
		if (_size == _capacity)
		{
			int newcapacity = _capacity * 2;
			DataType* temp = (DataType*)realloc(_array, newcapacity *
				sizeof(DataType));
			if (temp == NULL)
			{
				perror("realloc申请空间失败!!!");
				return;
			}
			_array = temp;
			_capacity = newcapacity;
		}
	}
private:
	DataType* _array;
	int _capacity;
	int _size;
};
int main()
{
	Stack s;
	s.Init();
	s.Push(1);
	s.Push(2);
	s.Push(3);
	s.Push(4);

	printf("%d\n", s.Top());
	printf("%d\n", s.Size());
	s.Pop();
	s.Pop();
	printf("%d\n", s.Top());
	printf("%d\n", s.Size());
	s.Destroy();
	return 0;
}

C++都有对象了,你还没有吗?,C++,c++,开发语言,c语言,数据结构

最后补充一个小知识:
局部域和全局域会影响生命周期
类域和命名空间域不会影响生命周期.文章来源地址https://www.toymoban.com/news/detail-573038.html

到了这里,关于C++都有对象了,你还没有吗?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构(c++语言版) 邓俊辉 第五章:二叉树学习笔记

    5.1二叉树及其表示         树是由节点和边组成的。 1.有根树         树是由顶点(vertex)和边(edge)组成。树的每个顶点也叫节点(node)。 2.深度与层次         由树的连通性,每一节点与根都有一条路径相连:根据树的无环性,由根通往每个节点的路径必然唯一。  

    2024年02月13日
    浏览(46)
  • 【数据结构大全】你想要的都有,数组、链表、堆栈、二叉树、红黑树、B树、图......

    作者简介: 目录 1.概述 2.线性结构 3.时间复杂度 4.查找算法 5.树 6.图 博主之前写过一个完整的关于数据结构的系列文章,一共十三篇,内容包含,数组、链表、堆栈、队列、时间复杂度、顺序查找、二分查找、二叉树、二叉搜索树、平衡二叉树、红黑树、B树、B+树、大顶堆

    2024年02月10日
    浏览(46)
  • 【C++技能树】再也不怕没有对象了 --初识类

    Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。 我们先来看看C语言解决一个问题的过程。 假设有以下这个场景:你需要把大象放进冰箱,你需要做哪几步? 打开冰箱门 拿起大象 把大象放进冰箱 关上冰箱门 这是用C语言解决一个问

    2024年02月05日
    浏览(33)
  • 【C++】引用之带你“消除”C语言版数据结构教材的一些困惑(虽然是C++的内容,但是强烈建议正在学习数据结构的同学点进来看看)

    👀樊梓慕: 个人主页  🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 引用的概念 引用的特性 引用的使用场景 引用和指针的区别 C语言版数据结构教材的解惑 不知道

    2024年02月08日
    浏览(46)
  • 软件开发中常用数据结构介绍:C语言队列

    工作之余来写写C语言相关知识,以免忘记。今天就来聊聊 C语言实现循环队列 ,我是分享人M哥,目前从事车载控制器的软件开发及测试工作。 学习过程中如有任何疑问,可底下评论! 如果觉得文章内容在工作学习中有帮助到你,麻烦 点赞收藏评论+关注 走一波!感谢各位的

    2024年02月11日
    浏览(48)
  • 数据结构中: 一元多项式的运算(相加,相减,相乘)------用C语言 / C++来实现。 数据结构线性表的操作和应用(顺序存储)

    线性表的操作和应用(顺序存储)。用顺序存储实现一元多项式,并进行加、减、乘运算。 (1)一元多项式结构体创建  (2)初始化 (3)一元多项式赋值             (4)打印一元多项式 (5)加法运算                        (6)减法运算 (7)乘法运算    全部代

    2024年02月01日
    浏览(65)
  • 05-1_Qt 5.9 C++开发指南_Model/View结构基础(基本原理;数据模型;试图组件;代理)

    Model/View(模型/视图) 结构是 Qt 中用界面组件显示与编辑数据的一种结构,视图 (View)是显示和编辑数据的界面组件,模型 (Model) 是视图与原始数据之间的接口。 Model/View 结构的典型应用是在数据库应用程序中,例如数据库中的一个数据表可以在一个 OTableView 组件中显示和编辑。

    2024年02月17日
    浏览(51)
  • 为什么 C 语言没有被 C++ 取代?

    今日话题,为什么 C 语言没有被 C++ 取代?C语言之所以没有被C++完全取代,有几个主要原因。首先,C++的编译器实现相对复杂,这对于一些嵌入式平台来说是一个问题。许多嵌入式系统只支持C语言,因此C++在这些平台上无法使用。即使在支持C++的嵌入式平台上,也常常存在不

    2024年01月19日
    浏览(70)
  • 视频融合平台可接入对象都有哪些?

    早期视频监控的应用相对独立和零散,但是随着网络技术的发展,以及万物互联时代的到来,在一些系统集成项目及综合管理应用中,视频融合的需求也越来越多。今天我们就以SkeyeVSS视频融合云平台为应用案例,盘点一下视频融合的对象都有哪些。 1、视频监控设备 视频监

    2024年02月05日
    浏览(53)
  • Redis数据结构与对象-字符串对象SDS

    Redis没有使用C的字符串,而是自己构建了简单动态字符串(Simple Dynamic String),简称SDS。通过这种字符串格式能够对redis字符串操作进行提速。下面介绍原理。 sds数据格式如下: 比如,一个sds 中存的是 “Redis” ,那么buf 中是一个char型的数组,存5个字符R, e,d,i,s len =5;free

    2023年04月16日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包