C++学习笔记(四): 类和对象

news2024/10/7 12:24:27

一个类定义了一个类型,以及与其关联的一组操作。类机制是C++最重要的特性之一。实际上,C++最初的一个设计焦点就是能定义使用上像内置类型一样自然的类类型(class type)。

在这里插入图片描述

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      double length;   // 长度
      double breadth;  // 宽度
      double height;   // 高度
      // 成员函数声明
      double get(void);
      void set( double len, double bre, double hei );
};

为了使用标准库设施,我们必须包含相关的头文件。类似的,我们也需要使用头文件来访问为自己的应用程序所定义的类。习惯上,头文件根据其中定义的类的名字来命名。

// 成员函数定义
double Box::get(void)
{
    return length * breadth * height;
}
 
void Box::set( double len, double bre, double hei)
{
    length = len;
    breadth = bre;
    height = hei;
}
#include <iostream>
#include "Box.h"

int main( )
{
   Box Box1;        // 声明 Box1,类型为 Box
   double volume = 0.0;     // 用于存储体积
   
   // box 1 详述
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;
   
   // box 1 的体积
   Box1.set(16.0, 8.0, 12.0); 
   volume = Box1.get(); 
   return 0;
}

1.认识头文件

此程序以两个#include指令开始,其中一个使用了新的形式。
包含来自标准库的头文件时,也应该用尖括号(<>)包围头文件名。
对于不属于标准库的头文件,则用双引号(" ")包围。

1.1 C++为什么会有头文件?

为什么不扫描所有.c文件,然后把其中的函数定义都找出来,生成统一的一个声明文件,以后编译每个.c文件的时候都依赖这个文件就可以了。类似于java那样。
原因如下:
(1)如果编译器想成功编译并链接某个源码文件,需要知道两点信息:数据类型和重定位信息。以Java为例,Java二进制包内存放有数据类型信息和重定位信息;而C++二进制库符号表内只存放了重定位信息,因此,若想成功编译链接C++源码,还需要头文件告知编译器数据类型信息。而早期的硬件存储空间还是运算能力都还不太够,通过.h/.c手动的把声明和实现分开来解决问题是个非常简单有效的办法。
(2)C语言设计之初是没有头文件的,数据都是定长的。但是后来出现了 short int 、long int ;char等类型,函数的调用者不知道压栈的长度。例如函数add(x,y)调用:应该是先压2个字节、再压4个字节喃,还是先压4个字节,再压2个字节;还是连续压2个4字节?在这种情况下,函数调用需要提前声明,以便让调用者得知函数的参数与返回值尺寸。
(3)C++最初是作为C语言的扩展而开发的,因此它继承了C语言的一些特性,例如单独编译和模块化设计。C++有头文件是要兼容C,而 C++ 的Module包含元数据信息还在委员会讨论之中。
(4)使用头文件的好处是可以将代码分为接口和实现两部分,接口定义在头文件中,实现定义在源文件中。这样可以避免每次都重新编译整个程序,提高编译速度。还可以有效地隐藏实现细节,提高代码的可读性和可维护性。
(5)此外,使用头文件还可以方便地共享代码,因为多个源文件可以包含同一头文件,从而共享其中的代码。

头文件(header)使类或其他名字的定义可被多个程序使用的一种机制。程序通过#include指令使用头文件。

1.2 如何编写头文件?

头文件通常包含那些只能被定义一次的实体,如类、const和constexpr变量等。头文件也经常用到其他头文件的功能。

编写头文件头文件常用的技术是预处理器

在C++中,预处理器是一种在编译之前对源代码进行预处理的程序。它主要用于实现一些在编译时无法完成的任务,例如包含头文件、宏定义、条件编译等。

(1)包含头文件:使用#include指令可以包含头文件,以便访问其中定义的函数、变量、类等内容。

#include <iostream>
#include "myheader.h"

(2)宏定义:使用#define指令可以定义一个宏,以便在源代码中使用。宏可以定义一个常量、一个函数、一个代码块等。

#define PI 3.1415926
#define MAX(a, b) ((a) > (b) ? (a) : (b))

(3)条件编译:使用#if、#ifdef和#ifndef等指令可以进行条件编译,以便根据条件选择编译不同的代码。
例如,我们使用#ifdef和#endif指令进行条件编译,当定义了DEBUG宏时,输出Debug mode;否则,输出Release mode。

#ifdef DEBUG
    cout << "Debug mode" << endl;
#else
    cout << "Release mode" << endl;
#endif

(4)文件包含:使用#include指令可以包含其他源代码文件,以便将多个源代码文件组合成一个程序。例如,我们使用#include指令包含了myheader.h和mysource.cpp两个源代码文件,以便将多个源代码文件组合成一个程序。

#include "myheader.h"
#include "mysource.cpp"

预处理器的主要作用是在编译之前对源代码进行处理,以便生成一个新的源代码文件,这个文件包含了预处理器指令所表示的内容。预处理器可以使代码更加模块化、可读、易于维护,从而提高编程效率和代码质量。

编写头文件时应该遵循以下规范:
(1)头文件应该包含防止重复包含的预处理器指令。例如,使用#ifndef、#define和#endif指令可以防止头文件被多次包含。

#ifndef MYCLASS_H
#define MYCLASS_H

#include <iostream>

// MyClass类的声明
class MyClass {
public:
    MyClass(int count);
    void print();
private:
    int m_count;
};

// MyClass类的实现
MyClass::MyClass(int count) : m_count(count) {}

void MyClass::print() {
    std::cout << "count = " << m_count << std::endl;
}

#endif
//包含了同一个头文件myheader.h两次
//并没有使用#ifndef、#define和#endif等预处理器指令来防止重复包含,从而导致链接错误。
#include "myheader.h"
#include "myheader.h"

(2)头文件应该包含必要的声明和定义,但不应该包含不必要的内容。例如,不应该在头文件中包含函数的实现代码,因为这会导致多个源代码文件包含同一个实现代码,从而导致链接错误。

//多次包含同一个头文件
#include <iostream>
#include <iostream>
//包含了string头文件,但是并没有在程序中使用string类型或相关函数。
//这样会增加编译时间和可执行文件大小,降低程序的性能。
#include <iostream>
#include <string>

(3)头文件应该使用全局唯一的命名规范,避免与其他头文件或变量名称冲突。一般建议使用项目名或类名作为头文件的前缀,例如MyClass.h。

(4)头文件应该避免包含其他头文件,除非这些头文件是必需的。如果必须包含其他头文件,应该在头文件中使用前向声明来避免循环包含。

//包含了myheader.h头文件,但在函数中使用了MyClass类型,却没有使用前向声明来告知编译器这个类型的存在。
//这会导致编译器无法在编译函数前找到MyClass类型的定义,从而导致编译错误。
#include "myheader.h"

// 使用MyClass类型
void func(MyClass obj) {
    // ...
}
// 前向声明MyClass类
class MyClass;

// 使用MyClass类型
void func(MyClass obj) {
    // ...
}

// 包含MyClass类的头文件
#include "myclass.h"
//在上面的代码中,我们使用class MyClass;语句进行了MyClass类的前向声明
//然后在函数中使用了MyClass类型。
//最后,我们包含了MyClass类的头文件myclass.h,以便访问MyClass类的实现。
// Forward declaration of class B
class B;

// Class A uses class B
class A {
public:
    void doSomething(B& b);
};

// Class C uses class A and class B
class C {
public:
    void doSomethingElse(A& a, B& b);
};

// Class B definition
class B {
public:
    void doSomething();
};

// Implementation of A::doSomething()
void A::doSomething(B& b) {
    b.doSomething();
}

// Implementation of C::doSomethingElse()
void C::doSomethingElse(A& a, B& b) {
    a.doSomething(b);
    b.doSomething();
}

在这个例子中,类C同时使用了类A和类B,如果直接在类C的头文件中包含类A和类B的头文件,很容易造成循环包含。使用前向声明可以避免这个问题。同时,由于类A和类B的定义分别在其他头文件中,所以在类A和类B的头文件中也必须使用前向声明来避免循环包含。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/574673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python坐标轴范围:如何设置?

Python 坐标轴范围&#xff1a;如何设置&#xff1f; 在 Python 中&#xff0c;通过 matplotlib 库绘图时&#xff0c;默认情况下该库会自动设置坐标轴范围。但是&#xff0c;在一些特殊情况下&#xff0c;我们可能需要手动设置坐标轴范围&#xff0c;以更好的呈现数据。那么&…

总结880

学习目标&#xff1a; 月目标&#xff1a;5月&#xff08;1800基础部分&#xff0c;背诵15篇短文&#xff0c;核心主词&#xff09; 周目标&#xff1a;1800高等数学部分并完成错题记录&#xff0c;英语背3篇文章并回诵 每日必复习&#xff08;5分钟&#xff09; 复习微分方…

014、检查点

检查点 检查点触发机制为什么需要检查点检查点工作流程检查点记录位置Database Recovery检查点调整checkpoint_completion_target检查点触发机制 在PostgreSQL中,检查点(后台)进程执行检查点;当发生下列情况之一时,其进程将启动: 检查点间隔时间由checkpoint_timeout设置…

chatgpt赋能python:Python倒序排序:如何通过Python实现快速高效地倒序排序?

Python倒序排序&#xff1a;如何通过Python实现快速高效地倒序排序&#xff1f; 在Python编程中&#xff0c;很可能遇到需要对列表、字典或其他数据结构进行排序的任务。排序可以按照从小到大或从大到小的顺序进行&#xff0c;本文将介绍如何使用Python进行倒序排序。倒序排序…

chatgpt赋能python:Python编译:Python程序变成机器可执行文件的过程

Python编译&#xff1a;Python程序变成机器可执行文件的过程 对于大多数Python编程人员来说&#xff0c;编译Python程序可能不是必须的&#xff0c;因为Python是一种解释型语言&#xff0c;我们可以直接运行源代码。但是&#xff0c;有时候&#xff0c;我们需要将Python程序编…

推箱子大冒险(SDL/C)

前言 欢迎来到小K的SDL专栏第三小节&#xff0c;本节将为大家带来小项目~C语言SDL版坤坤推箱子详细讲解&#xff0c;这里也为大家上传了源码和图片资源&#xff0c;需要的自取看完以后&#xff0c;希望对你有所帮助 ✨效果如下 文章目录 前言一、推箱子思路讲解二、加SDL绘图代…

chatgpt赋能python:Python字符串颠倒:如何用Python实现字符串颠倒操作

Python字符串颠倒&#xff1a;如何用Python实现字符串颠倒操作 在Python中&#xff0c;字符串颠倒是一种常见的操作。我们可以使用Python内置的方法和函数来轻松地完成字符串颠倒操作。在本篇文章中&#xff0c;我们将深入探讨Python字符串颠倒操作的实现方法。 什么是字符串…

Fiddler抓包MuMu模拟器中app的数据

第1步&#xff1a;下载Fiddler&#xff0c;并安装。 下载链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/105XDJ_KD54PUnsHM-BsZLQ?pwd0t8q 提取码&#xff1a;0t8q 第2步&#xff1a;配置Fiddler。 点击“Tools”→点击“Options” → 重启生效 设置HTTPS: …

chatgpt赋能python:Python如何排序

Python 如何排序 Python 是一门强大的编程语言&#xff0c;拥有许多常用的排序算法。在本文中&#xff0c;我们将介绍Python 中的常用排序算法&#xff0c;包括插入排序、选择排序、冒泡排序、快速排序和归并排序。 插入排序 插入排序是最简单的排序算法之一。它将列表分为已…

chatgpt赋能python:Python字符串的首字母小写是什么?

Python字符串的首字母小写是什么&#xff1f; Python是一种广泛使用的编程语言&#xff0c;被许多工程师和开发者用于各种应用程序的开发。字符串操作是Python中常见的任务之一&#xff0c;其中一个常见的需求是将字符串中的第一个字符小写。本文将介绍如何在Python中实现这个…

mysql window安装教程

官网下载 https://dev.mysql.com/downloads/mysql/解压后根目录新建mysqlConfig.ini[mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 basedirE:\Soft\MySQL\mysql-8.0.27-winx64 # 设置mysql数据库的数据的存放目录 datadirE:\Soft\MySQL\mysql-8.0.27-winx64\da…

【实现一个简单的前后端交互页面】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 客户端与服务器之间的通信流程 理解当前案例…

【短信业务】阿里云可以发送带变量的链接短信

阿里云配置短信业务1.在账号管理中的 Accesskey管理中申请accessKeyId和accessKeySecret2.进入短信服务管理3.进入快速学习和测试申请签名&#xff1a;按照要求填写信息&#xff0c;审核一般两三个小时左右申请模板 &#xff1a;按照要求填写信息&#xff0c;审核一般两三个小时…

python+django高校就业求职招聘信息服务系统_8ryq3

本文论述了高校就业信息服务系统的设计和实现&#xff0c;该网站从实际运用的角度出发&#xff0c;运用了计算机网站设计、数据库等相关知识&#xff0c;基于系统管理和Mysql数据库设计来实现的&#xff0c;网站主要包括用户、企业、人才库、面试邀请、岗位分类、招聘信息、应聘…

【IM群发推内容参考iMessage苹果推】下面的 mailto、news 和 isbn URI 都是 URN 的示例。

要实现APNs认证以用于iMessage推送&#xff0c;以下是一样平常的步调&#xff1a; 建立苹果开发者账户&#xff1a;确保你具有苹果开发者账户。若是没有&#xff0c;请注册一个开发者账户。 登录到苹果开发者中间&#xff1a;利用你的开发者账户登录到苹果开发者中心&#xf…

凭据收集工具 Legion 瞄准额外的云服务

黑客在受感染的 Web 服务器上部署的名为 Legion 的商业恶意软件工具最近已更新&#xff0c;可以提取额外云服务的凭据以通过 SSH 进行身份验证。 这个基于 Python 的脚本的主要目标是获取存储在电子邮件提供商、云服务提供商、服务器管理系统、数据库和支付系统的配置文件中的…

【Python】循环语句 ③ ( while 嵌套循环案例 - 打印乘法表 | print 不换行打印 | tab 制表符 )

文章目录 一、print 不换行打印二、tab 制表符三、while 嵌套循环案例 - 打印乘法表 一、print 不换行打印 使用 print 函数打印字符串 , 会进行自动换行 ; Python 中的 print 函数原型如下 : def print(self, *args, sep , end\n, fileNone): 默认情况下 , print 打印字符串…

MVC模式和三层架构(附综合案例增删改查)

MVC模式和三层架构 MVC模式 MVC 是一种分层开发的模式&#xff0c;其中&#xff1a; M&#xff1a;Model&#xff0c;业务模型&#xff0c;处理业务 V&#xff1a;View&#xff0c;视图&#xff0c;界面展示 C&#xff1a;Controller&#xff0c;控制器&#xff0c;处理请求…

【ISO14229_UDS刷写】-5-$38诊断服务RequestFileTransfer理论部分

总目录&#xff1a;&#xff08;单击下方链接皆可跳转至专栏总目录&#xff09; 《UDS/OBD诊断需求编辑工具》总目录https://blog.csdn.net/qfmzhu/article/details/123697014 目录 1 $0x38 RequestFileTransfer诊断服务描述 2 0x38服务请求消息 2.1 0x38服务请求消息定义…

MongoDB window安装教程

官网下载 MongoDB&#xff1a;https://www.mongodb.com/try/download/community MongoDB shell脚本&#xff1a;https://www.mongodb.com/try/download/shell&#xff0c;下载后解压到MongoDB安装目录创建数据库文件的存放位置 在data文件夹下创建 db 文件夹&#xff08;启动 …