首页 > 编程语言 >在C语言基础上的C++第二章(类和对象)

在C语言基础上的C++第二章(类和对象)

时间:2024-12-26 12:57:56浏览次数:8  
标签:定义 void C++ C语言 student 内联 第二章 成员 函数

1:面向对象的程序设计

我们学习过的C语言是一种面向过程的程序设计。思想是把问题分割成一个个函数,然后用主函数把它们串联起来。

而C++是面向对象的程序设计。面向对象的程序设计(Object - Oriented Programming,简称 OOP)是一种编程范式,它以对象为核心来组织程序结构。他具有以下四个特征:

1:抽象性:许多实体的共性产生类。

2:封装性:类将数据和操作封装为用户自定义的抽象数据类型。

3:继承性:类能被重复利用,具有继承(派生)机制。

4:多态性:具有动态联编机制。

2:类的定义

类是一种用户定义的数据类型,它就像是一个蓝图或者模板,用于创建对象。例如,在建造房子时,建筑图纸就是 “类”,而根据这个图纸建造出来的一个个具体的房子就是 “对象”。

1:从结构体到类

C语言里的结构体,以一个学生为例

struct student{
int no;//学号
char name[20];//姓名
float score;//分数
};

下面我们在C++里面定义一个类,看看有什么相同之处

class student{
int no;
char name[20];
float score;
void display(){
  cout<<"学号"<<no<<endl;
  cout<<"姓名"<<name<<endl;
  cout<<"分数"<<score<<endl;
  }
};

标准C里面是不允许在结构体里面声明函数的,但是C++的类的定义不仅包含数据而且包含对数据进行操作的函数。这点与C有着本质区别,很好地体现了C++面向对象的特点。

这种将数据和对数据进行操作的函数放在一起的做法称为封装。

封装在类中的成员(数据和函数)与外界是无法接触的,这样十分安全,但如果完全与外界隔绝,这样的类就无实际意义了。就像display函数,外界无法使用。所以我们一般情况下,会把数据隐藏起来,而把对数据的操作作为与外界的公共的接口与外界联系。所以我们可以这样定义

class student{
private://以下成员是私有的
  int no;
  char name[20];
  float score;
public://以下成员是公有的
void display(){
  cout<<"学号"<<no<<endl;
  cout<<"姓名"<<name<<endl;
  cout<<"分数"<<score<<endl;
  }
};

如果在类里面不指定private和public,那么默认都是private私有的。

但是在struct里面默认都是公有的。

2:类的格式

class 类名

{ private:

数据成员和成员函数;

protected:

数据成员和成员函数;

public:

数据成员和成员函数;

}:

3:对象的定义

类是抽象的,定义的student类不是指哪个特定学生。利用类可以像定义变量一样定义对象。

例如

class student{
private:
  int no;
  char name[20];
  float score;
public:
void display(){
  cout<<"学号"<<no<<endl;
  cout<<"姓名"<<name<<endl;
  cout<<"分数"<<score<<endl;
  }
};
class student s1;
student s2;

 1:对象的定义格式

我们可以使用

class 类名 对象名 //class student s1;

这是第一种方法,符合C语言的写法

还可以使用

类名 对象名//student s2;

这是第二种定义方法,是C++的特色

2:对象成员的访问

和C语言中一样我们对于对象名使用"."符合来访问,对于对象的指针我们使用"->"来访问。

在这里就不多说了。

4:类的成员函数

一般的函数

void display(student s){
  cout<<"学号"<<s.no<<endl;
  cout<<"姓名"<<s.name<<endl;
  cout<<"分数"<<s.score<<endl;
  }

在一般函数中,不能直接使用数据成员了,而要加上对象名称才能使用。

但成员函数是在类中定义的,可以直接使用数据成员。

1:this指针

在 C++ 中,this指针是一个隐含于每一个非静态成员函数中的特殊指针。它指向调用该成员函数的对象。简单来说,当你调用一个对象的成员函数时,编译器会自动将这个对象的地址通过this指针传递给成员函数。

例如定义一个student的变量s1

void display(){
  cout<<"学号"<<this->no<<endl;
  cout<<"姓名"<<this->name<<endl;
  cout<<"分数"<<this->score<<endl;
  }
};

相当于执行了

void display(){
  cout<<"学号"<<s1.no<<endl;
  cout<<"姓名"<<s1.name<<endl;
  cout<<"分数"<<s1.score<<endl;
  }
};

2:成员函数的重载

成员函数与一般函数一样,也可以重载

看以下程序

#include<iostream>
using namespace std;

class student {
public:
	void set()
	{
		cout << "请输入学号,姓名,分数" << endl;
		cin >> no >> name >> score;
	}
	void set(int n,const char na[], float s)
	{
		no = n;
		strcpy(name, na);
		score = s;
	}
	void display()
	{
		cout << "学号" << no << endl;
		cout << "姓名" << name << endl;
		cout << "分数" << score << endl;
	}
private:
	int no;
	char name[20];
	float score;
};

int main()
{
	student s1, s2;
	s1.set();
	s2.set(999, "伪人",88.8);
	s1.display();
	s2.display();
	return 0;
}

set函数进行重载。

注意:我们传递的"伪人"是一个常量字符串,需要使用const来保证可读性

3:在类外定义成员函数

类中的所有成员函数一般都需要在类中声明,但是如果成员函数体比较大,在类里面定义非常不方便,所有我们可以在类的外面定义成员函数

格式如下

返回值类型 类名::成员函数名(参数列表)

{ // 函数体 }

看下面例子,将上述代码这样定义

在类里面进行函数的声明,在类外面进行函数体的书写。

class student {
public:
	void set();
	void set(int n, const char na[], float s);
	void display();
private:
	int no;
	char name[20];
	float score;
};
void student::set()
{
	cout << "请输入学号,姓名,分数" << endl;
	cin >> no >> name >> score;
}

void student::set(int n, const char na[], float s)
{
	no = n;
	strcpy(name, na);
	score = s;
}
void student::display()
{
	cout << "学号" << no << endl;
	cout << "姓名" << name << endl;
	cout << "分数" << score << endl;
}

5:运算符::(作用域运算符)

引用别人的blog吧,不是本节重点。

https://blog.csdn.net/sangyongqi/article/details/139770556?ops_request_misc=%257B%2522request%255Fid%2522%253A%252266682c2d07aa2536bae9814fd325f1a5%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=66682c2d07aa2536bae9814fd325f1a5&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-139770556-null-null.142^v100^pc_search_result_base8&utm_term=%3A%3A%E8%BF%90%E7%AE%97%E7%AC%A6&spm=1018.2226.3001.4187

6:声明成员函数为内联函数

内联函数是一种以关键字inline修饰的函数。当编译器处理内联函数调用时,不会像处理普通函数那样进行函数调用的开销(如入栈、出栈操作等),而是直接将函数体的代码插入到函数调用处。可以近似理解成宏,但又和宏有区别。

1:为什么有内联函数

1:提高执行效率

避免函数调用时的入栈、出栈等开销,直接将函数体代码插入调用处,对于频繁调用的简单函数,能显著减少执行时间,提升程序运行速度。

2:增强代码可读性

可以把具有特定功能的代码封装成函数形式,使主程序逻辑更清晰,即使是简单操作,也能让代码结构更有条理,易于阅读和理解。

3:优化小型函数

针对小型的、功能单一的操作,如简单数学运算、类型转换等,内联函数在保证代码模块化的同时,能有效优化程序性能,减少不必要的函数调用开销。

2:内联函数和宏的区别

1:语法方面
  • 内联函数:使用inline关键字修饰,有完整的函数声明和函数体,遵循函数语法规则。
  • 宏定义:通过#define指令定义,只是简单的文本替换,无函数声明和函数体。
2:调用机制
  • 内联函数:编译时将函数体插入调用处,遵循函数调用流程,有参数传递和局部变量创建等。
  • 宏定义:预处理时进行文本替换,不涉及函数调用过程及相关操作。
3:参数检查
  • 内联函数:编译时进行严格的参数类型检查,类型不匹配会报错。
  • 宏定义:只是文本替换,不进行参数类型检查,可能导致潜在错误。
4:可读性与调试
  • 内联函数:代码可读性好,可像普通函数一样调试。
  • 宏定义:可读性相对较差,无法像函数那样调试。

5:作用域和生命周期

  • 内联函数:具有普通函数的作用域和生命周期,局部变量在每次调用时重新创建和销毁。
  • 宏定义:作用域从定义处到文件末尾,预处理后不存在宏定义本身概念。
6:可维护性
  • 内联函数:修改功能只需在定义处修改,维护方便。
  • 宏定义:修改功能需在所有使用处检查修改,易遗漏,维护困难。

标签:定义,void,C++,C语言,student,内联,第二章,成员,函数
From: https://blog.csdn.net/2403_87752060/article/details/144722678

相关文章

  • C和C++编程语言中的前向声明简介
    前向声明(ForwardDeclaration)是C和C++编程语言中的一种技术,用于在不需要完整类型定义的情况下,声明一个类型即将存在。这种技术主要用于减少头文件的相互依赖,以及加快编译速度。一、前向声明的概念在C和C++中,当一个类型(如结构体、联合体、类或枚举)在另一个类型之前被引用时,通......
  • VC++申请和释放内存问题(常发生在C code 转 VC++时)
    注意看,VC++环境下,用malloc申请内存空间的代码如下:编译显示成功,但在执行释放内存代码free(p);free(q);时报错。经过分析发现,p是结构体linkqueue指针,linkqueue结构体中有两个指针变量front,rear,在队列为空时,front和rear都指向头节点q.点击查看代码linkqueuep=(li......
  • C++中的类继承知识点总结1(13章)
    一)类继承总结继承通过使用已有的类(基类)定义新的类(派生类),使得能够根据需要修改编程代码。公有继承建立is-a关系,这意味着派生类对象也应该是某种基类对象。作为is-a模型的一部分,派生类继承基类的数据成员和大部分方法,但不继承基类的构造函数、析构函数和赋值运算符。派......
  • 【最新原创毕设】基于PPH的花涧订购系统+00332(免费领源码)可做计算机毕业设计JAVA、PHP
    摘 要近年来,电子商务的快速发展引起了行业和学术界的高度关注。花涧订购系统旨在为用户提供一个简单、高效、便捷的花卉购物体验,它不仅要求用户清晰地查看所需信息,而且还要求界面设计精美,使得功能与页面完美融合,从而提升系统的可操作性。因此,我们需要深入研究信息内容,并利用......
  • 栈,数据结构中的栈(C语言实现,新手必看)
    对于逻辑关系为“一对一”的数据,除了用顺序表和链表存储外,还可以用栈结构存储。栈是一种“特殊”的线性存储结构,它的特殊之处体现在以下两个地方:1、元素进栈和出栈的操作只能从一端完成,另一端是封闭的,如下图所示:通常,我们将元素进栈的过程简称为“入栈”、“进栈”或者“压......
  • LeetCode 209. 长度最小的子数组 (C++实现)
    1.题目描述给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的子数组[numsl,numsl+1,…,numsr-1,numsr],并返回其长度。如果不存在符合条件的子数组,返回0。示例1:输入:target=7,nums=[2,3,1,2,4,3]......
  • c语言期末复习----指针
    一、指针基础知识1指针概念:指针是一个值为内存地址的变量2格式:指针在使用前一定要有明确指向(初始化)1)先声明再初始化 2)声明的同时初始化 inta,*p=&a;注:关于指针p的三个相关的值1)p,p里面存放着一个地址2)*p,p指向的对象的值3)&p,表示变量p本身的地址3*的作用1)定义指......
  • 【C/C++】字符数组和string字符串:从C语言到C++的演变
    字符数组和string字符串:从C语言到C++的演变在C语言和C++的编程中,字符数组和字符串(string)是非常重要的基础数据类型。它们在实际编程中常用于存储和操作文本数据,但是这两种类型的处理方式有所不同。在这篇博客中,我们将详细讲解字符数组和string字符串,从C语言的字符数组到C++......
  • 力扣第四十二题 接雨水(困难难度,c语言附着解析)
    代码如下这个代码是双指针算法,我参考了别人的解法,大致的思路如下,我们先使用两个指针,分别从数组开始和末尾开始遍历,并且我们使用了两个变量,分别记录当前我们遍历到的左边和右边遇到的最大高度。这里为什么要进行height[l]小于或大于的判断再进行相加,根据木桶效应,我们需要......
  • leetcode热题100(54. 螺旋矩阵)c++
    链接:54.螺旋矩阵-力扣(LeetCode)给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。示例1:输入:matrix=[[1,2,3],[4,5,6],[7,8,9]]输出:[1,2,3,6,9,8,7,4,5]示例2:输入:matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]输出:[1,2......