【侯捷C++面向对象 】(上)

news2025/1/26 15:38:22

1.C++ 编程简介 & 目标

  • 培养代码正规编范
  • class 分为 带pointer 和 不带pointer的

image.png

  • 学习C++ : 语言 + 标准库

2.C vs C++

  • C语言 : (type)数据 + 函数 —create—》 数据s
  • C++ : (class ) 数据 + 成员 —create—》 对象
  • 不带指针的类 :complex 复数
  • 带指针的类 : string 字符串
  • 如果是自己写的头文件 那就必须加上防卫式的声明

image.png

  • 头文件布局:

image.png

  • 然后就是body/ 函数设计
  • 函数可以直接在body定义 (inline 函数) 或者 在外部定义
  • inline 函数 :比较快 比较好 并不是什么函数都可以是 inline 如果函数太复杂就不行, 能否inline 仍然又编译器决定。
  • private : 数据部分 写函数调用获取 prublic 俩部分可以分很多段写

3.构造函数

  • C++ 如果创建一个对象 ,自动调用的函数 就是构造函数
  • 函数名称 与 类名称一样
  • 初值列表 : 构造函数独有的 , 不适用 赋值的方式 先执行初值列表,再执行body里面的, 如果使用赋值 就会影响效率 比较差

image.png

  • 构造函数不需要写类型 不带指针的类多半不需要写虚构函数
  • 构造函数可以有很多个 overloading(重载)
  • 构造函数如果放在private 区 将无法被外界调用 但可以使用单例模式 进行设计

image.png

  • 凡是对不会改变的变量 通通加上const 变成常量成员函数

image.png

  • 如果定义是const 但是 real 和imag、函数都没加const 则会报错

image.png

传参 or 传引用?

  • 传值的话,值多大 就传多大,传的动作加上压到函数的栈里面去, 多少个byte就穿多少, 传指针 == 传地址 4byte
  • 传引用 0 byte , 比指针更好 , 相当于传指针, 快, 最好都是传引用 , 如果传过去的变量,不希望对方修改,那么就必须加上const

返回传递 return by value vs return by reference(to const)

  • 如果在可以的情况下 必须 return by reference(to const)
  • 如果不是(局部)local object 就可以传引用
  • 比如在函数中创建一个变量, 然后对这啊 v f个变量进行return by referenbce, 变量脱离函数就会销毁, 所以不能 return by referenbce

友元 friend

  • 设置friend 就可以直接获取 和public一样, 但是不写friend 获取就只能通过函数,效率会下降.

  • image.png

05 image.png

  • 首要考虑 & 然后再看 , 使用 & 会不会出错,如果会就改80

4.操作符重载

complex.h

#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__

class complex; 
complex&
__doapl (complex* ths, const complex& r);
complex&
__doami (complex* ths, const complex& r);
complex&
__doaml (complex* ths, const complex& r);


class complex
{
public:
complex (double r = 0, double i = 0): re (r), im (i) { }
complex& operator += (const complex&);
complex& operator -= (const complex&);
complex& operator *= (const complex&);
complex& operator /= (const complex&);
double real () const { return re; }
double imag () const { return im; }
private:    
double re, im;

friend complex& __doapl (complex *, const complex&);
friend complex& __doami (complex *, const complex&);
friend complex& __doaml (complex *, const complex&);
};


inline complex&
__doapl (complex* ths, const complex& r)
{
    ths->re += r.re;
    ths->im += r.im;
    return *ths;
}

inline complex&
complex::operator += (const complex& r)
{
    return __doapl (this, r);
}

inline complex&
__doami (complex* ths, const complex& r)
{
    ths->re -= r.re;
    ths->im -= r.im;
    return *ths;
}

inline complex&
complex::operator -= (const complex& r)
{
    return __doami (this, r);
}

inline complex&
__doaml (complex* ths, const complex& r)
{
    double f = ths->re * r.re - ths->im * r.im;
    ths->im = ths->re * r.im + ths->im * r.re;
    ths->re = f;
    return *ths;
}

inline complex&
complex::operator *= (const complex& r)
{
    return __doaml (this, r);
}

inline double
imag (const complex& x)
{
    return x.imag ();
}

inline double
real (const complex& x)
{
    return x.real ();
}

inline complex
operator + (const complex& x, const complex& y)
{
    return complex (real (x) + real (y), imag (x) + imag (y));
}

inline complex
operator + (const complex& x, double y)
{
    return complex (real (x) + y, imag (x));
}

inline complex
operator + (double x, const complex& y)
{
    return complex (x + real (y), imag (y));
}

inline complex
operator - (const complex& x, const complex& y)
{
    return complex (real (x) - real (y), imag (x) - imag (y));
}

inline complex
operator - (const complex& x, double y)
{
    return complex (real (x) - y, imag (x)); // 被减数
}	

inline complex
operator - (double x, const complex& y)
{
    return complex (x - real (y), - imag (y));  // 减数
}

inline complex
operator + (const complex& x)  // 正值
{
    return x;
}

inline complex
operator - (const complex& x)  // 负值
{
    return complex (-real (x), -imag (x));
}


inline complex
operator * (const complex& x, const complex& y)
{
    return complex (real (x) * real (y) - imag (x) * imag (y),
        real (x) * imag (y) + imag (x) * real (y));
}

inline complex
operator * (const complex& x, double y)
{
    return complex (real (x) * y, imag (x) * y);
}

inline complex
operator * (double x, const complex& y)
{
    return complex (x * real (y), x * imag (y));
}

complex
operator / (const complex& x, double y)
{
    return complex (real (x) / y, imag (x) / y);
}


inline bool
operator == (const complex& x, const complex& y)
{
    return real (x) == real (y) && imag (x) == imag (y);
        }

        inline bool
        operator == (const complex& x, double y)
    {
        return real (x) == y && imag (x) == 0;
        }

        inline bool
        operator == (double x, const complex& y)
    {
        return x == real (y) && imag (y) == 0;
        }

        inline bool
        operator != (const complex& x, const complex& y)
    {
        return real (x) != real (y) || imag (x) != imag (y);
        }

        inline bool
        operator != (const complex& x, double y)
    {
        return real (x) != y || imag (x) != 0;
        }

        inline bool
        operator != (double x, const complex& y)
    {
        return x != real (y) || imag (y) != 0;
        }

        #include <cmath>

        inline complex
        polar (double r, double t)
    {
        return complex (r * cos (t), r * sin (t));
        }

        inline complex
        conj (const complex& x)  //鍏辫江澶嶆暟
    {
        return complex (real (x), -imag (x));
        }

        inline double
        norm (const complex& x)
    {
        return real (x) * real (x) + imag (x) * imag (x);
        }

        #endif   //__MYCOMPLEX__

5.类的区分

image.png
就是成员函数是否带指针

6.浅拷贝 & 深拷贝

在 C++ 中,浅拷贝和深拷贝是两种不同的复制对象的方法。浅拷贝是通过简单地复制原始对象的所有变量的数据来创建一个对象。这种方法适用于对象的变量没有在堆内存区域定义的情况。如果某些变量是从堆内存区域动态分配的内存,则复制的对象变量也将引用相同的内存位置。这将导致歧义和运行时错误,悬空指针。由于两个对象都将引用相同的内存位置,因此一个对象所做的更改也会反映在另一个对象上。由于我们希望创建一个对象的副本,因此浅拷贝无法实现这一目的。
image.png
深拷贝是通过复制所有变量的数据并为对象分配相同值的类似内存资源来创建一个对象。为了执行深拷贝,我们需要显式地定义复制构造函数并根据需要分配动态内存。此外,还需要在其他构造函数中为变量动态分配内存 。

inline
String::String(const String& str)  // 拷贝本身   收到的参数就是它本身 
{
   m_data = new char[ strlen(str.m_data) + 1 ];
   strcpy(m_data, str.m_data);
}

image.pngimage.png
准确性 !!
image.png

7.stack和heap

  • Stack 是存在于某作用域 (scope) 的一块内存空间 (memory space)。例如当你调用函数,函数本身即会形成一个 stack 用来放置它所接收的参数,以及返回地址。在函数本体 (function body) 内声明的任何变量,其所使用的内存块都取自上述 stack。
  • Heap,或谓 system heap,是指由操作系统提供的一块 global 内存空间,程序可动态分配 (dynamic allocated) 从某中获得若干区块 (blocks)。希望这些信息对您有所帮助!如果您有其他问题,请随时告诉我。
  • 你可以在程序的任何地方new 它, 但是你就必须要有delete 它的职责。

image.png
image.png
image.png

new & delete操作

  • newdelete 都会调用 C语言 中的 mallocfree函数

image.png
memory block
image.png

image.png

  • 保证万无一失

image.png

string类

#ifndef __MYSTRING__
#define __MYSTRING__

class String
{
public:                            
//   如果成员函数为指针  , 必须重写拷贝构造 和 拷贝复制 , 
// 不然系统会 一个字节一个字节复制  
String(const char* cstr=0);  //拷贝构造                          
String(const String& str);  //拷贝构造   拷贝本身()              
String& operator=(const String& str);  // 拷贝复制        
~String();                                    
char* get_c_str() const { return m_data; }  // 获取c风格的 str
private:
char* m_data;
};

#include <cstring>

inline
String::String(const char* cstr)
{
    if (cstr) {
        m_data = new char[strlen(cstr)+1];
        strcpy(m_data, cstr);
    }
    else {   
        m_data = new char[1];
        *m_data = '\0';
    }
}

inline
String::~String()
{
    delete[] m_data;
}

inline
String& String::operator=(const String& str)  // 
{
    if (this == &str)  // 检测自我赋值 
        return *this;

    delete[] m_data;
    m_data = new char[ strlen(str.m_data) + 1 ];
    strcpy(m_data, str.m_data);
    return *this;
}

inline
String::String(const String& str)  // 拷贝本身 
{
    m_data = new char[ strlen(str.m_data) + 1 ];
    strcpy(m_data, str.m_data);
}

#include <iostream>
using namespace std;

ostream& operator<<(ostream& os, const String& str)
{
    os << str.get_c_str();
    return os;
}
#endif

8.Static

image.png

  • static example : 利率 每个人都一样
  • static 控制static 变量
  • image.png
  • static 变量只有定义后才会出现
  • 一种设计模式 : 将构造函数 放在 private 里面

image.png

  • cout 和 模板

image.png
image.png

9.继承、符合、委托

Composition (複合)

image.png

  • 内存部分 : 内存空间

image.png

  • 调用顺序

image.png

Delegation (委托 ). Composition by reference.

  • 用指针相连 , 字符串怎么设计 , 怎么实现,都在另一个类来实现 。
  • pImpl : point to implement 可实现 引用计数 & 共享

image.png

Inheritance (繼承), 表示 is-a

image.png

  • 内存关系 :

image.png

10.虚函数与多态

  • override 重写 这个名词是针对于继承设计的
  • non-virtual 非虚函数:你不希望派生类重写 (override, 覆盖) 它。
  • virtual虚函数:你希望派生类重写 (override, 覆盖) 它,且你对它已有默认定义。
  • pure virtual 纯虚函数:你希望派生类一定要重写 (override 覆盖) 它,你对它没有默认定义

image.png
image.png

Delegation (委託) + Inheritance (繼承)

如何设计几个窗口, 内容是共享的, 一个改变 另外的类也会改变 ?

image.png

  • Observer 设计模式 :

image.png

11.委托相关设计

image.png
image.png

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

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

相关文章

AI伦理:科技发展中的人性之声

文章目录 AI伦理的关键问题1. 隐私问题2. 公平性问题3. 自主性问题4. 伦理教育问题 隐私问题的拓展分析数据收集和滥用隐私泄露和数据安全 公平性问题的拓展分析历史偏见和算法模型可解释性 自主性问题的拓展分析自主AI决策伦理框架 伦理教育的拓展分析伦理培训 结论 &#x1f…

【LeetCode-中等题】34. 在排序数组中查找元素的第一个和最后一个位置

文章目录 题目方法一&#xff1a;二分查找&#xff08;先找到mid&#xff0c;在根据mid确定左右区间&#xff09;方法二&#xff1a;分两次二分查找&#xff0c;一次用于找左区间&#xff0c;一次用于找右区间 题目 方法一&#xff1a;二分查找&#xff08;先找到mid&#xff0…

第六讲:如何构建类的事件(上)

【分享成果&#xff0c;随喜正能量】世界上凡是人聚集的地方&#xff0c;讨论的话题无外乎三个&#xff1a;拐弯抹角的炫耀自己、添油加醋的贬低别人、相互窥探的搬弄是非。人性的丑陋就是&#xff1a;在无权无势、善良的人身上挑毛病&#xff1b;在有权有势的人身上找优点。。…

【硬件设计】硬件学习笔记二--电源电路设计

硬件学习笔记二--电源电路设计 一、LDO设计1.1 LDO原理1.2 LDO参数1.3 应用 二、DC-DC设计2.1 DC-DC原理2.2 DC-DC参数介绍2.4 DC-DC设计要点2.5 DC-DC设计注意事项 写在前面&#xff1a;本篇笔记来自王工的硬件工程师培训课程&#xff0c;想要学硬件的同学可以去腾讯课堂直接搜…

【LeetCode-中等题】69. x 的平方根

文章目录 题目方法一&#xff1a;二分查找 题目 方法一&#xff1a;二分查找 假设求8的平方根&#xff0c;那就设置left 0 &#xff0c;right 8&#xff1b; 每次取最中间的元素的平方和8对比&#xff0c;如果大于8&#xff0c;则right mid-1&#xff0c;如果小于8 left mi…

第二节 极限 (一)

一、极限的定义(了解) 二、求极限的方法 (重点 大题8分 选择4分 填空4分) (1) 直接代入 (只要有意义) (2) 洛必达法则&#xff08;80%解题法&#xff09; (3) 无穷小和无穷大的性质 (4) 三种特例 (5) 两个重要极限 (6) 等价无穷小的替换 三、真题 方法一&#xff…

蓝桥杯官网填空题(振兴中华)

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小明参加了学校的趣味运动会&#xff0c;其中的一个项目是&#xff1a;跳格子。 地上画着一些格子&#xff0c;每个格子里写一个字&#xff0c;如下所示&#xff1…

字符编码(idea)

File----------settings-------------Editor------------File Encodings

常见IO模型(非常详细)

背景知识 常⽤5中⽹络IO模型 阻塞IO&#xff08;Blocking IO&#xff09;⾮阻塞IO&#xff08;Non-Blocking IO&#xff09;多路复⽤IO&#xff08;IO Multiplexing&#xff09;信号驱动IO&#xff08;Signal Driven IO&#xff09;异步IO&#xff08;Asynchronous IO&#x…

IPD-PDT-POP角色的名称、定位和职责说明书

在IPD推进中&#xff0c;有一个不是很关键但却离不开的角色叫做POP&#xff0c;POP这个角色通常是设置在PDT团队中。 那么IPD的PDT团队中的POP这个角色到底是什么意思呢&#xff1f;POP如何开展工作&#xff0c;以及POP的主要岗位职责有哪些呢&#xff1f;华研荟今天给大家分享…

一文解码语言模型:语言模型的原理、实战与评估

目录 一、语言模型概述什么是语言模型&#xff1f;核心概念和数学表示挑战&#xff1a;高维度和稀疏性链式法则与条件概率举例 应用场景小结 二、n元语言模型&#xff08;n-gram Language Models&#xff09;基本概念数学表示 代码示例&#xff1a;计算Bigram概率输入与输出 优…

极简极速-Bitset (bitmap)实现考勤打卡场景

文章目录 1. redis命令行操作bitmap2. RedisTemplate操作bitmap3. Java中的Bitset 1. redis命令行操作bitmap 2. RedisTemplate操作bitmap bitmap的常见业务场景主要有日活统计&#xff08;类似的月考勤&#xff09;、点赞、BloomFilter等&#xff0c;以用户mj考勤统计为例&am…

掌握AI助手的魔法工具:解密`Prompt`(提示)在AIGC时代的应用(下篇)

前言&#xff1a;在前面的两篇文章中&#xff0c;我们深入探讨了AI助手中的魔法工具——Prompt&#xff08;提示&#xff09;的基本概念以及在AIGC&#xff08;Artificial Intelligence-Generated Content&#xff0c;人工智能生成内容&#xff09;时代的应用场景。在本篇中&am…

【前端小tip】深拷贝不能处理函数的解决方法,文末包含所有深拷贝常见问题的解决方法

在开发过程中&#xff0c;我对对象进行深拷贝的时候常常使用序列化和反序列化&#xff0c;也就是 const newObj JSON.parse(JSON.stringify(obj))这个方法很好用&#xff0c;但是在最近我发现了一个弊端&#xff0c;就是它只能处理只含有基础类型属性和对象属性的对象&#x…

Python专辑:大话数字类型

I will honour myself by showing up powerfully in my life today。我会为在今日努力生活的自我而感到自豪。 前面我们讲解过关于用Python写温度转换器&#xff0c;画“Python”以及天天学习的代码讲解。不知大家是否还记得&#xff0c;忘记的可以点击上面的专辑去里面复习一下…

反编译小程序详细教程,处理各种异常报错

文章目录 一、准备工作 &#xff08;一&#xff09;安装Nodejs &#xff08;二&#xff09;解密和逆向工具 二、小程序缓存文件解密 &#xff08;一&#xff09;定位小程序缓存路径 &#xff08;二&#xff09;源码解密 &#xff08;三&#xff09;源码反编译 三、小结 四、异常…

PTA作业笔记——简单的计算

PTA作业笔记——简单的计算 7-10 整数算术运算7-11 猫是液体7-11 猫是液体7-13 计算4个整数的平均值7-14 公元前后日期格式化7-15 A除以B7-18 出租车计价 7-10 整数算术运算 本题要求编写程序&#xff0c;计算并输出2个正整数的和、差、积、商与余数。题目保证输入和输出全部在…

数据集笔记 geolife (操作篇)

数据集介绍可看&#xff1a;数据集笔记:GeoLife GPS 数据 &#xff08;user guide&#xff09;_UQI-LIUWJ的博客-CSDN博客 1 读取数据 import os os.chdir(D:/Geolife Trajectories 1.3/Geolife Trajectories 1.3/Data/000/Trajectory)import pandas as pd data pd.read_csv(…

深度学习(Python)学习笔记2

第二章 感知机 2.1 感知机是什么 感知机接收多个输入信号,输出一个信号。 感知机的信号会形成流,向前方输送信息。 感知机的信号只有“流/不流”(1/0)两种取值。 本学习笔记中,0对应“不传递信号”,1对应“传递信号”。 图中、是输入信号,是输出信号,、是权重。图…

WebSocket和Html通讯

一、使用到的相关链接 参考 opencv-websocket: 基于opencv-web的实现 https://github.com/zaphoyd/websocketpp 安装教程 Websocket安装使用 - 知乎 (zhihu.com) 二、编译教程&#xff08;Ubuntu为例&#xff09; 遇到相关问题可以参考&#xff1a;Websocket安装使用 - 知乎…