c++ 命名空间、三大特征以及封装性

名字空间

namespace 的基础与扩展

#include <iostream>
using namespace std;namespace ns
{int a = 3;float f(int x){return x / 2;}namespace ns_ns	// 可以进行嵌套{int a = 6;float f(int x){return x / 3;}  }
}namespace ns
{int b = 5;	// 直接扩充成员
}int main()
{cout << ns::a << endl;	// 使用自创的名字空间,必须要告知来源cout << ns::f(6) << endl;cout << ns::ns_ns::a << endl;	// 同样的,嵌套使用必须说明来源cout << ns::ns_ns::f(6) << endl;cout << ns::b << endl;return 0;
}若两个命名空间出现相同名字,则只需在调用时明确告知来源即可,
如:假设存已命名空间 name 内部包含 a,则cout << ns::a << endl;
cout << name::a << endl;

面向对象三大特征

封装

把对象的属性和功能结合成一个独立的系统单位。(尽可能隐藏内部细节,对外形成屏障)

如:人使用电脑,只需要知道键位功能,不需要知道键位是如何绑定函数调用的。

继承

若类的对象A拥有另一个类B的全部属性与服务,称作类A对类B的继承。

如:机动车共有特性发动机,而小汽车、摩托车等都继承了该共有属性。

多态

指在一般类中定义的属性或行为,被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或行为在一般类及其各个 特殊类中具有不同的语义

类的封装

类与对象的定义

相似于 c 语言的结构体,但存在以下区别:

1、含有作用域限定符

2、含有函数,也就是类的自身行为(类方法)

#include <iostream>using namespace std;class A
{public:	// 若不添加,默认是 privateint a;private:// 类方法:类中的函数void show(){cout << a << endl;}
};int main()
{A a1;a1.a = 10;a1.show();	// 通过类产生的对象来调用方法return 0;
}

类成员权限限定符

公有成员(public):任何地方都可以访问

保护成员(protected);只能在本类或其他后代类中访问

私有成员(private);只能在本类中访问

一般原则:1、类数据属性,设定为私有;2、类方法,设定为公有;#include <iostream>
using namespace std;class Kitty
{public:void eat() { cout << "吃饭" << endl; }void sleep() { cout << "睡觉" << endl; }void actCute() { cout << "卖萌" << endl; }void f() { cout << "父类 f" << endl; }
};class A : public Kitty
{public:void f() { cout << "子类 f" << endl; }
};int main()
{Kitty myCat;myCat.eat();myCat.sleep();myCat.actCute();myCat.f();	// Kitty::f();A a;a. f	 	();	// A::f(); 在本来对象可以简写调用a. Kitty::f	();	// 此时在子类调用从父类继承下来的方法,只需要明确说明即可return 0;
}注意:被 protected 和 private 修饰,不可以被类直接调用

类的构造函数

概念:类的特殊成员,专门用于初始化类的各项数据(分配内存、变量初始化)

特点:

1、任何类都必然有至少一个构造函数,可以重载

2、若类显式定义构造函数,则默认无参构造函数会被取消(调用系统默认构造函数,这样就无法得知构造函数干啥。所以不要使用系统的默认构造函数);若无显示定义构造函数,则系统会自动添加一个隐式构造函数

3、每当分配一个类对象时,构造函数会被自动调用

4、构造函数无返回值类型(不是void),且必须与类名相同

5、构造函数不被设置为静态成员函数,构造函数的函数首部之前或之后不能用const修饰

#include <iostream>
using namespace std;class Node
{public:// 特别注意:下面这种情况,两种构造函数都写了,那么就看对象创建时是否带参数// 若默认无参构造函数未显式写出,而类对象创建时不带参数,那么就会报错,因为没有匹配的构造函数Node() { cout << "我是默认构造函数" << endl; }Node(int a) { cout << "我是显式的构造函数,我的编号是:" << a << endl; }Node(int a, float b);	// 函数重载private:string name;	// 不可以直接赋值int high;
};int main()
{// 动态分配会在堆区,而不会出现在栈区,这就是需要动态分配的原因Node node;// Node *node = new Node;	//普遍应用的一种方式,通过 new 可以调用构造函数,这是 malloc 不具备的(本质就是 new 除了会分配内存,还会调用构造函数进行变量初始化,而 malloc 只能分配内存,不能初始化)return 0;
}小小认知:( 变量 )初始化:本质是为变量申请开辟内存空间,并没有直观的体现赋值:将数值存储在已初始化变量上,就是存储在内存空间中所以,构造函数的变量初始化是为了更加细化的给变量分配内存空间

this 指针

#include <iostream>
using namespace std;class Node
{public:Node(string name) { this->name = name }	// 用来区分哪个是传参,哪个是本身,当然可以不用相同的名字// 若要返回本身Node f() { return *this; }private:string name;	// 不可以直接赋值int high;
};int main()
{Node node("老六");return 0;
}

类的析构函数

概念:类的特殊成员,专门用于处理类对象被释放时的收尾工作

特点:

1、任何类有且仅有一个析构函数,不可以重载

2、若类显式定义析构函数,则默认无参构造函数会被取消;若无显示定义析构函数,则系统会自动添加一个隐式析构函数

3、每当释放一个类对象时,析构函数会被自动调用

4、构造函数无返回值类型(不是void),也没有参数,且必须与类名相同,且在前面多一个波浪号

5、如果类对象的作用域相同,那么销毁时析构函数的执行顺序与构造函数相反

#include <iostream>using namespace std;class Node
{public:Node() { cout << "我是构造函数" << endl; }~Node() { cout << "我是析构函数" << endl; }
};int main()
{Node *node = new Node;delete node;return 0;
}

拷贝构造函数

一种特殊的构造函数,其作用是在构造对象时,复制其他对象的所有成员。

1、拷贝构造函数,要求形参中有一个当前类的类对象

2、若没有就使用默认,若存在则使用存在的,特别需要注意的是:显式的拷贝构造函数基本不会影响已存在的默认拷贝构造函数,除非提供了单参构造函数,且参数类型是类类型的引用

3、拷贝分为浅拷贝和深拷贝,浅拷贝只拷贝值,深拷贝还会拷贝内存(这样也就不会导致重复释放同一个空间)

4、若显示声明和定义拷贝构造函数后,类中的的所有成员变量需要手动拷贝

5、当使用一个老对象去构造一个新对象时会调用拷贝构造函数,如果没有显示声明和定义拷贝构造函数时,类中的非指针类成员的值可以拷贝。默认拷贝构造函数负责执行了值的拷贝

三种应用场景:

(1)用一个老对象构造一个新对象,或者新对象赋给老对象

(2)当函数的形参是一个非引用的类对象时,形参对实参的传递时

(3)函数返回一个非引用的类对象时

#include <iostream>using namespace std;class Node
{public:Node(int a) { cout << a << endl; }Node(const Node &p) { cout << "调用拷贝构造" << endl; }
};int main()
{Node *node = new Node(1);Node *node1 = node;	// 会自动调用拷贝构造函数delete node;delete node1;	// 这会导致 double free ,所以需要进行深拷贝(将内存空间也要拷贝一份)return 0;
}
-------------------------------------------------- 深拷贝与浅拷贝 --------------------------------------------------
系统默认拷贝构造是浅拷贝,也就是相当于取别名,复制多个指针,但还是指向同一块内存空间。这样就会造成一个结果:重复释放了某一块内存空间,所以一般需要深拷贝以下重点讲解怎么进行深拷贝:#include <iostream>
#include <string>
using namespace std;class A
{public:A() { p = new char[100]; }~A() { delete p; }// 将拷贝构造函数进行重写,另外需要开辟空间,改造成深拷贝A(const A &r){if(r.p != nullptr){p = new char[100];memcpy(p, r.p, 100);}elsep = nullptr;}private:char *p;int a;
}

空类中默认的类方法

无参构造函数 析构函数 拷贝构造函数 赋值运算符函数

const 成员

const基本语义就是将其修饰的符号作只读化处理(不可修改)。

#include <iostream>
using namespace std;class person
{public:person();~person();private:const unsigned int ID;	// const 修饰类成员变量public:void studentInfo() const;	// const 修饰类方法
};// 方式一:类构造函数初始化列表中初始化
person::person(unsigned int id): ID(id)
{}// 方式二:类定义语句中初始化
class person
{private:const unsigned int ID = 12345;
};注意:1、方式一可以通过构造函数传递不同的参数来给 ID 不同初始值 ---- 适用场景:学生的学号2、方式二则是所有对象被构造出来的 ID 都是一样的且不可修改 ---- 适用场景:学生的学校
-------------------------------------------------- 实际代码展示 ---------------------------------------------------
#include <iostream>
using namespace std;class Student
{private:const string schoolName = "粤嵌";	// 所有成员都在这个学校const int ID;public:Student(int id): ID(id)	// 所有类对象都会有不同的 ID{}// 打印学生信息void showInfo() const	// 提高程序运行效率,只要确保该函数不会修改数据,就可以使用 const{cout << "我的学校" << schoolName << endl;cout << "我的ID" << ID << endl;}
};int main()
{Student *luo = new Student(1);luo->showInfo();	// 重要认知:类成员方法是可以直接使用类成员属性的,并不需要传参。return 0;
}注意:1、类方法的 const 关键字,要放在函数参数列表之后2、在类方法 声明 和 定义 中都需要加上 const ,因为这是重载的依据之一3、被 const 修饰的类方法不能访问类的非 const 方法,也不能对该类的其他数据成员赋值

类静态成员的设计和语法

当类成员被static修饰时,被称为静态成员。(本质:限制其作用域范围)

类成员数据:表达类的属性,而不是具体对象的属性

类成员方法:表达类的行为,而不是具体对象的行为

#include <iostream>
using namespace std;class Student
{private:// 个人信息(单个对象属性)unsigned int ID;string name;// 群体信息(类类型本身的属性)static int total;	// 总人数public:Student() { total++; }~Student() { total--; }// 获取学生总人数static void totalStudentNumber();	// 不依赖于类而存在{cout << "总人数:" << total << endl;}
};// 静态数据成员,必须在类外定义
int Student::total;		// 本质:将全局的作用数据修改其作用域void totalStudentNumber();	
{cout << "总人数:" << total << endl;
}int main()
{Student jack;Student::totalStudentNumber();	// 可以不依赖对象调用jack.totalStudentNumber();	// 也可以用类对象调用return 0;
}注意:1、静态类成员( 静态数据区 )与普通成员存储空间不一样2、静态类成员不属于任何一个对象,是共有的,只有一份3、静态类方法只能调用其他静态类方法或引用类静态数据,不能调用普通方法和数据(因为后者有归属者,说不定不存在)小补充:当构造函数被private修饰-------设计模式:单例模式
class Node
{public:static Node* getInstance();private:Node();private:static Node* m_ptr;
};Node* Node::m_ptr = NULL;Node::Node()
{cout << "123" << endl;
}Node* Node::getIstance()
{if(m_ptr == NULL){m_ptr = new Node;	// 这样设定就是为了只被构造一次}return m_ptr;
}int main()
{Node* n = Node::getInstance();cout << n << endl;return 0;
}

初始化列表

#include <iostream>
using namespace std;class Score
{private:float math;		// 数学成绩float history;	// 历史成绩public:Score(float m=0, float h=0): math(m), history(h){}
};class Student
{private:int age;			// 普通类成员const string name;	 // const型类成员Score score;		// 类对象成员public:Student(int a, string n, Score &s)	// & 这里采用引用就只构造一次: age(a), name(n), score(s)	// 初始化列表{}showInfo() { cout << "数学和历史:" << math << history << endl; }
};int main()
{Score score(98, 89);Student student(22, "罗宏斌", score);student.showInfo();return 0;
}const 型类成员和类对象成员必须在初始化列表中进行初始化,为免去记忆,全部在初始化列表中初始化类组合
#include <iostream>
using namespace std;class AAA
{public:AAA()  { cout << "AAA" << endl; }~AAA() { cout << "~AAA" << endl; }private:int m_AAA;
};class A
{public:A()  {cout << "A" << endl;}~A() {cout << "~A" << endl;}private:int m_A;
};class B
{public:B(int n) : m_B(n) {cout << "B" << endl;}~B() {cout << "~B" << endl;}private:int m_B;
};class C
{public:// 不仅要负责对本类中的基本类型成员数据赋初值,也要对对象成员初始化。C(int x, int y) : b(x), m_C(y) { cout << "C" << endl; }~C() {cout << "~C" << endl;}private:A a;B b;AAA* aaa;int m_C;
};int main(int argc, char *argv[])
{// 类对象产生时,其构造顺序:// 1、先构造成员变量// 2、再调用构造函数C c(11, 12);return 0;
}

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

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

相关文章

机器学习—神经网络中的层

大多数现代神经网络的基本组成部分是一层神经元&#xff0c;本篇文章中&#xff0c;你将学会如何构造一层神经元&#xff0c;一旦你把它放下&#xff0c;你就能把那些积木&#xff0c;把它们放在一起形成一个大的神经网络。 一层神经元是如何工作的&#xff1f; 下面是我们从…

51单片机教程(四)- 点亮LED灯

1、项目分析 让输入/输出口的P1.0连接一盏LED灯进行点亮。 2、技术准备 1 LED组成 ​ 说明 二极管有 P型 和 N型材料构成&#xff0c;通常是&#xff1a;硅/锗 掺杂其他元素&#xff08;硼、磷等&#xff09; 电子是带负电的&#xff0c;是负电荷的载体&#xff0c;电子流…

青训1_1105_03 最小替换子串长度

.md 文章目录 请添加图片描述一 问题描述测试样例示例 二 思路个人思路(ERROR)思路&#xff08;right&#xff09; !!解题思路 详细答案三、理解1、 理解嵌套循环:也就是连续子串的所有可能性位置-看懂了2、问题又来了&#xff0c;即使确定了能得到不同长度连续子串&#xff0c…

222页PPT集团公司供应链管理SOP计划管理流程规划

S&OP&#xff08;Sales & Operations Planning&#xff09;&#xff0c;即销售与运营计划&#xff0c;也被称为产销协同&#xff0c;是一种综合性的企业管理方法。以下是对S&OP计划管理流程规划的详细内容&#xff1a; 一、S&OP的基本概念与目的 S&OP是一…

第三十五篇:HTTP报文格式,HTTP系列二

HTTP 是超⽂本传输协议&#xff0c;也就是HyperText Transfer Protocol。 前面我们讲到第三章中网络协议的定义&#xff0c;网络协议的定义&#xff1a;网络协议是通信计算机双方必须共同遵从的一组约定。就像两个人要进行交流&#xff0c;如果不制定一套约定&#xff0c;一方…

华夏教育集团《梦回延安》全国巡演河南站纪实

传承红色精神&#xff0c;推动中国式家校共育。日前&#xff0c;由华夏教育集团太阳谷华夏学校携手河南少年先锋学校、世纪先锋学校联合推出的大型红色舞台剧《梦回延安》在河南省人民会堂精彩亮相。 河南是中华文明的发祥地之一&#xff0c;此次《梦回延安》舞台剧首次走出辽宁…

Idea如何推送项目到gitee

第一步&#xff1a;先在你的gitee创建一个仓库 第二步&#xff1a; 点击推送 点击定义远程&#xff0c;将URL换成你仓库的&#xff0c;填好你的用户名和密码 可以看到已经推送到仓库了

Leecode:977. 有序数组的平方

题目 ——Leecode:977. 有序数组的平方 目录 题目 ——Leecode:977. 有序数组的平方 题目分析 暴力解法&#xff1a; 双指针解法&#xff1a; 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排…

动态规划-两个数组的dp问题——44.通配符匹配

1.题目解析 题目来源&#xff1a;44.通配符匹配——力扣 测试用例 2.算法原理 1.状态表示 本题属于两个数组的dp问题&#xff0c;这里需要使用p中的字符消去s中的字符且p中有特殊字符可以匹配s中的普通字符&#xff0c;属于寻找相同子序列的变式&#xff0c;所以需要一个二维d…

Linux命令 - 目录与文件基本操作

文章目录 1 文件系统树2 几个特殊的目录3 绝对路径与相对路径4 文件系统中跳转与浏览4.1 文件系统中跳转4.2 查看目录内容4.2.1 ls命令详解4.2.2 确定文件类型示例 5 操作目录与文件5.1 强大的通配符5.2 复制目录/文件5.3 移动/重命名目录/文件5.4 删除目录/文件5.5 创建目录5.…

基于STM32的自动化植物浇灌系统教学

引言 随着城市化进程的加快&#xff0c;越来越多的人开始关注家庭园艺与植物养护。基于STM32的自动化植物浇灌系统可以帮助用户在忙碌的生活中顺利管理植物的水分需求。本教学文章将指导您如何利用STM32构建一个简单实用的植物浇灌系统&#xff0c;实现自动浇水功能。 环境准备…

美格智能5G车规级通信模组: 5G+C-V2X连接汽车通信未来十年

自2019年5G牌照发放开始&#xff0c;经过五年发展&#xff0c;我国5G在基础设施建设、用户规模、创新应用等方面均取得了显著成绩&#xff0c;5G网络建设也即将从基础的大范围覆盖向各产业融合的全场景应用转变。工业和信息化部数据显示&#xff0c;5G行业应用已融入76个国民经…

【CRM系统选型指南:国内八大主流工具比较】

本文将对十大主流CRM系统进行比较&#xff1a;纷享销客、Zoho CRM、Pipedrive、简信CRM、HubSpot CRM、八百客CRM、金蝶CRM、浪潮CRM、销售易CRM 本文将深入评比2024年主流的CRM系统&#xff0c;帮助你了解各系统之间的主要区别、优缺点以及当前的发展趋势。通过详细的比较和分…

node.js的exports使用误区解释

exports和module.exports指向同一个对象&#xff0c;最终共享的结果&#xff0c;以module.exports指向的对象为准。 exports 和 module.exports 使用误区 使用require()导入的模块&#xff0c;使用的永远是module.exports指向的对象 实例1 exports.age 23 module.exports {n…

Maven项目的基础配置:利用IDEA将SpringBoot的项目打包成war文件

文章目录 引言Maven项目的聚合与继承(依赖管理)把项目打包成war包其他打包配置引言 利用IDEA将SpringBoot的项目打包成war文件Maven项目的聚合与继承(依赖管理)Maven项目的聚合与继承(依赖管理) 把项目打包成war包 利用IDEA将SpringBoot的项目打包成war文件:要配置启动…

Nuxt.js 应用中的 nitro:config 事件钩子详解

title: Nuxt.js 应用中的 nitro:config 事件钩子详解 date: 2024/11/2 updated: 2024/11/2 author: cmdragon excerpt: nitro:config 是 Nuxt 3 中的一个生命周期钩子,允许开发者在初始化 Nitro 之前自定义 Nitro 的配置。Nitro 是 Nuxt 3 的服务器引擎,负责处理请求、渲…

51c大模型~合集14

我自己的原文哦~ https://blog.51cto.com/whaosoft/11603879 # LLM 结构化数据生成原理 如何结合人工规则让 LLM 输出符合 JSON 格式的数据。 目前 LLM&#xff08;Large Language Model&#xff09;从文本补全到内容创作&#xff0c;都展示出了强大的生成能力。然而通过 L…

CSRA的LINUX操作系统24年11月2日下午上课笔记

压缩和解压缩&#xff1a;zip 、gzip、bz、xz # zip 压缩 # 压缩文件夹 # 解压缩 # unzip -v 查看压缩包中的内容 # bzip2 dir1/* :将dir1中的所有文件压缩 # gzip # 压缩文件夹 # 解压缩 tar 归档命令&#xff1a; # 创建tar包 tar -c*f # 释放tar包 tar -xf[c] # c …

MyBatis 返回 Map 或 List<Map>时,时间类型数据,默认为LocalDateTime,响应给前端默认含有‘T‘字符

一、问题 MyBatis 返回 Map 或 List时&#xff0c;时间类型数据&#xff0c;默认为LocalDateTime Springboot 响应给前端的LocalDateTime&#xff0c;默认含有’T’字符&#xff0c;如何统一配置去掉 二、解决方案 1、创建配置类&#xff0c;对ObjectMapper对象进行定制&am…

数据结构算法篇--递归(c语言版)

目录 1.递归 1.1求阶乘&#xff1a; 1.2.斐波那契数 1.3. 求幂 1.递归 在C语言中&#xff0c;递归是一种函数调用自身的方法&#xff0c;用来解决一些具有重复性质的问题。例如&#xff0c;计算阶乘、斐波那契数列等问题都可以通过递归实现。 递归在书写的时候&#xff0…