【C++深学日志】C++“类”的完全指南--从基础到实践(一)

【C++深学日志】C++“类”的完全指南--从基础到实践(一)
假想一下,你是一个顶级汽车设计师,你的任务不是亲自拧紧每一个螺丝,而是要设计出一幅“汽车蓝图”,你在图纸上设计了一辆汽车所需的一切:车轮、车灯、V8发动机、方向盘等,你手上这份设计好的蓝图就相当于我们今天要讲的C++中的“类”,它规定了汽车的属性(例如:离合器)和方法(功能:换挡),它本身并不是一辆真正的汽车,只是你的一份设计规划,后续你交付给工厂,工厂按照你的设计蓝图,生产出了一辆汽车,这就是实例化,后续工厂有根据你的蓝图设计了一条流水线,每一辆从流水线上生产下来的车辆,都是里这个蓝图(类)的一个对象,他们都有蓝图定义的属性和功能。在C++中类就充当着蓝图的作用,它定义了对象拥有哪些属性,那么就和我一起来揭开这份“蓝图”的面纱吧。

1.类

1.1.类的定义

类的基本思想是数据抽象封装,数据抽象是一种依赖于接口和实现的分离式编程技术,类的接口包括用户所能执行的操作,类的实现则是包括类的数据成员、负责接口实现的函数以及定义类所需的各种私有函数。封装实现了类的接口和实现的分离,封装后的类隐藏了他的视线细节,也就是说,用户只能使用指定的接口而无法访问实现部分。类想要实现数据抽象和封装,首先需要定义一个抽象数据类型,在抽象的数据类型中,由类的设计者负责考虑类的实现过程,使用该类型的程序员则只需要考虑类型做了什么,而无需了解类型的工作细节。

C++中通过关键字class来定义一个类,类的定义通常包括类名、访问限定符、成员变量和成员函数,类的定义格式如下:

class classname{ public: //公有成员变量,可以被直接访问 classname(); //类的构造函数后面会讲解 ~classname(); //类的析构函数 void test(); //成员函数 private: //私有成员变量,只能被类的成员函数和友元函数访问 int a; //私有成员变量 protect: //受保护的成员,可以被类的派生类所访问 int b; //受保护的成员变量 };

这里面有好多我们没有接触过的概念,放心先不急,一点一点来,都会讲到的。其中,class定义一个类,classname为定义的类名,{}所包含的为类的主体,特别注意:定义类结束时{}外面的分号不能像定义函数一样被省略。类主体中的内容被称为类成员,类中的变量被称为成员变量,类中的函数被称为成员函数。

成员函数的定义分为类内定义和类外定义,类内定义:在函数体内直接定义,一般地这一类函数会被编译器隐式地当作内联函数处理:

class classname { public: void setname(const std::string& Name) { name=Name; } private: std::string name; };

类外定义:在类内声明函数,然后再类外面使用作用域解析运算符::来定义函数体:

class classname { public: void setname(const std::string& Name); private: std:string name; }; void classname::setname(const std::string& Name) { name=Name; }

大家应该发现我在前两个类定义的例子中传入的形参和类内的成员变量相同,为了区分我将形参的首个字母大写处理了,这种方法其实不太好,我们在工作中难免会遇到这种情况,如果一时疏忽忘了区分大小写,这时候处理起来会非常麻烦,为了区分成员变量,我们一般习惯为成员变量加一个特殊标识,我用习惯了在成员变量前加"_",这样我们在区分时会非常方便,举个例子:

class Date { public: void Init(int year,int month,int day) { _year=year; _month=month; _day=day; } private: int _year; int _month; int _day; };

1.2访问限定符

C++中访问限定符是面向对象编程中实现封装的基石,访问限定符主要用于控制类成员的访问权限,访问限定符决定了类的成员(包括成员变量和成员函数)是否可以被类外的代码或其他类访问,C++提供了三种主要的访问限定符:public、private、protected。

1.2.1piblic访问限定符

public访问限定符表示类的成员可以被类外面的代码直接访问,换句话说,public成员对任何人都是可见的。通常用于类的接口,即那些希望被外部代码访问的成员函数和变量:

class MyClass { public: int publicVar; //公有成员变量 void publicFunction() //公有成员函数 { // 此处省略函数体 } }; int main() { MyClass obj; obj.publicVar = 10; // 可以直接访问 obj.publicFunction(); // 可以直接调用 return 0; } 

1.2.2private访问限定符

private访问限定符表示类的成员只能被类的成员函数和类的友元函数访问,不能被类外的代码直接访问。通常用于隐藏类的内部实现细节,确保类的封装,通常将成员设置成private,为了防止直接从类的外部直接修改类成员的值,从而提升代码的安全性和稳定性:

class Myclass { public: //用来展现类内的成员函数可以直接访问private的成员 void publicFunction(int a) { privateVal=a; } private: int privateVal;//private的成员 }; int main() { Myclass test; test.privateVal=10; test.publicFuntion(10); return 0; }

在这里我们可以看到报错反馈:不可访问。这就是private访问限定符将成员保护起来了,阻止外界直接对其值随意修改。那怎么证明类的成员函数可以直接访问private的成员呢?打个断点和监视窗口我们来看看private成员的值有没有发生改变被修改成10:

1.2.3protected访问限定符

protected访问限定符表示类的成员可以被类的成员函数、友元函数以及类的派生类访问,不能被类外的代码直接访问。大家是不是觉得protected访问限定符和刚刚的private访问限定符好像,只是多了一个可以被派生类所访问,其实他就是public和private的一种折中的结果,现在大家可以先把它的功能理解为和private一样,等到后面继承时会详细讲解他俩的区别,现在我就为大家简单的实现一下可以被派生类访问这一个例子:

class Myclass { protected: int val; }; class test:public Myclass { public: void Function(int a) { val=a; printf("val=%d",val); } }: int main() { test SL; SL.Function(10); return 0; }

这时候又该有小伙伴说了:这两次限定符都能被友元函数所访问你怎么没实现,因为后面会单独对它进行讲解,那时候会有很多例子让大家可以清楚的感知到这一特性。

1.3类域

在C++中,类域也被称为类作用域,指的是类成员(成员变量和成员函数)的作用范围和可见性,其和C语言中函数的作用域差不多。我们知道局部域和全局域是会影响生命周期的,因为它会影响对象是否存在不用的作用域内,局部的会存在函数的栈帧中,函数结束就销毁了,而静态、全局域则会存在静态区里,main函数创建之前就已经存在,当main函数结束时才会销毁。类作用域和命名空间都不影响生命周期,只会影响查找规则,同一个作用域内不能出现相同的变量名,不同的作用域是可以创建同名变量的。类的成员都是在类作用域内的,类外定义成员函数时必须使用作用域解析运算符(::)来指明类域:

class Date { public: void Init(int year, int month, int day); private: int _year; int _month; int _day; }; void Date::Init(int year, int month, int day) { _year = year; _month = month; _day = day; } int main() { Date time; time.Init(2025,9,21); return 0; }

在C++中静态成员变量必须在类外定义和初始化,这是由静态成员和新特性和C++编译链接模型共同决定的,这样主要是为了确保静态成员变量在程序的所有使用场合中只有一次定义,避免多重定义错误,并明确其独特的生命周期和存储位置。

class Myclass { public: static int val; }; int Myclass::val=10; 

生命和定义分离的核心原因:在类内使用static关键字对成员变量进行声明,仅仅像编译器说明这是一个该类的静态变量,并不会实际分配内存,定义的的作用是真正为变量分配空间,C++遵循“一次定义规则”(只能有一次定义,但可以有多次声明),为了确保整个程序中静态成员变量只有唯一的一次定义,这个定义必须放到类外(通常放到.cpp文件中),避免了多个源文件包含同一个头文件而出现的重复定义的错误:

静态成员变量不属于任何对象,它存放于静态区,其生命周期与程序同步,这种全局特性决定了它的初始化不能依赖于对象的创建,要在程序开始时完成初始化,在类外初始化正式为了满足他这一特性。

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=bgh7lptdufj

Read more

【讨论】VR + 具身智能 + 人形机器人:通往现实世界的智能接口

【讨论】VR + 具身智能 + 人形机器人:通往现实世界的智能接口

摘要:本文探讨了“VR + 具身智能 + 人形机器人”作为通往现实世界的智能接口的前沿趋势。文章从技术融合、应用场景、商业潜力三个维度分析其价值,涵盖工业协作、教育培训、医疗康复、服务陪护等领域,并展望VR赋能下的人机共生未来,揭示具身智能如何推动机器人真正理解、感知并参与现实世界。 VR + 具身智能 + 人形机器人:通往现实世界的智能接口 文章目录 * VR + 具身智能 + 人形机器人:通往现实世界的智能接口 * 一、引言:三股力量的融合,正在重塑现实世界 * 二、具身智能:让AI拥有“身体”的智慧 * 1. 什么是具身智能(Embodied Intelligence) * 2. 为什么VR是具身智能的“孵化器” * 三、VR + 具身智能 + 人形机器人:协同结构与原理 * 1. 系统组成 * 2. 人类的“

By Ne0inhk
Flutter 组件 bip340 适配鸿蒙 HarmonyOS 实战:次世代 Schnorr 签名,为鸿蒙 Web3 与隐私计算筑牢加密防线

Flutter 组件 bip340 适配鸿蒙 HarmonyOS 实战:次世代 Schnorr 签名,为鸿蒙 Web3 与隐私计算筑牢加密防线

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 bip340 适配鸿蒙 HarmonyOS 实战:次世代 Schnorr 签名,为鸿蒙 Web3 与隐私计算筑牢加密防线 前言 在鸿蒙(OpenHarmony)生态迈向去中心化金融(DeFi)、隐私通讯及安全资产管理等高阶安全场景的背景下,如何实现更高性能、更具扩展性且抗攻击能力的数字签名架构,已成为决定应用闭环安全性的“压舱石”。在鸿蒙设备这类强调分布式鉴权与芯片级安全(TEE/SE)的移动终端上,如果依然沿用传统的 ECDSA 签名算法,由于由于其固有的可延展性风险与高昂的聚合验证成本,极易由于由于在大规模节点验证时的 CPU 负载过高导致交互滞后。 我们需要一种能够实现签名线性聚合、计算逻辑极简且具备原生抗延展性的密码学方案。 bip340 为 Flutter 开发者引入了比特币 Taproot 升级的核心——Schnorr 签名算法。它不仅在安全性上超越了传统标准,更通过其线性的数学特性,

By Ne0inhk
《MySQL 表基础语法:从入门到熟练的核心技巧》

《MySQL 表基础语法:从入门到熟练的核心技巧》

前引:MySQL 表的增删查是数据库操作的基础,也是日常开发、数据分析中最高频的需求。很多初学者会卡在语法细节、场景适配或效率优化上,明明掌握了基础命令,实际应用中却频频出错。本文聚焦 “实用 + 避坑”,从核心语法到高频场景,再到优化技巧,帮你彻底吃透 MySQL 表增删查,告别 “只会用不会用对” 的尴尬 SQL查询中各个关键字的执行先后顺序: from > on> join > where > group by > with > having > select > distinct > order by > limit 目录 【一】增 (1)基本创建 (2)

By Ne0inhk
Spring Boot 4.0 与 Spring Cloud Alibaba 2025 整合完整指南

Spring Boot 4.0 与 Spring Cloud Alibaba 2025 整合完整指南

Spring Boot 4.0 与 Spring Cloud Alibaba 2025 整合完整指南 Spring Cloud全栈实战:手撸企业级项目,从入门到架构师! 概述 本文将详细介绍如何在 Spring Boot 4.0 中整合 Spring Cloud Alibaba 2025 最新版本。Spring Cloud Alibaba 为分布式应用开发提供了一站式解决方案,包含服务发现、配置管理、流量控制等核心功能。 环境要求 Spring Cloud全栈实战:手撸企业级项目,从入门到架构师! * JDK: 21+ (Spring Boot 4.0 要求) * Maven: 3.6+ 或 Gradle

By Ne0inhk