C++中的类: const, static和友元
constconst成员函数要点: 成员函数都有一个隐含参数this。 对于非const成员函数,this的类型是A* const: 指针是const(不能改指针本身),但指向的对象可被修改。 对于const成员函数(在函数名后写了const),this的类型是const A* const: 指针不可变且指向const A,表示不能修改对象的非mutable成员。 成员函数后加const表示“承诺不修改对象的可观察状态”。对应的隐含this类型是const A* const(指针不可改且指向const对象)。有时在查询函数中希望做惰性计算/缓存(例如计算 Fibonacci 并缓存结果),这属于“内部实现细节”,从外部观察对象状态并不改变。为了在const函数内仍能修改这些内部缓存,使用mutable修饰成员。 1234567891011121314151617181920class A { int x;public: void f() { x = 1; } // 等价为void f(A* const this);...
C++中的类: 构造与析构
类类的定义如下,以简单的TDate为例: 1234567891011121314class TDate {public: void SetDate(iny y, int m, int d) { year = y; month = m; day = d; } int IsLeapYear() { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); }private: int year, month, day;} 在类中定义且实现了的函数(SetDate(), IsLeapYear())编译器会自动内联,即隐式内联。 不能在类中直接像int year = 2000这样初始化函数(C++11前,之后可以对非静态成员这样进行初始化),需要定义构造函数来进行初始化: TDate() : year(2000)...
LeetCode刷题笔记(十四): 图
数据结构介绍:图通常分为有向(directed)或无向(undirected),有循环(cyclic)或无循环(acyclic),所有节点相连(connected)或不相连(disconnected)。树即是一个相连的无向无环图,而另一种很常见的图是有向无环图(Directed Acyclic Graph,DAG)。 补充:图通常有两种表示方法。假设图中一共有n个节点、m条边。第一种表示方法是邻接矩阵(adjacency matrix):我们可以建立一个n×n的矩阵G,如果第i个节点连向第j个节点,则G[i][j]=1,反之为0;如果图是无向的,则这个矩阵一定是对称矩阵,即G[i][j]=G[j][i]。第二种表示方法是邻接链表(adjacency...
函数调用约定: cdecl, stdcall, fastcall
一、cdeclcdecl(C declaration,即C声明)是源起C语言的一种调用约定,也是C语言的事实上的标准。 主要要求如下: 函数实参在线程栈上按照从右至左的顺序依次压栈。 函数结果保存在寄存器EAX/AX/AL中。 编译后的函数名前缀是一个下划线字符。 调用者负责从线程栈中弹出实参(即清栈)。 例子如下: 1234567891011int main() { int r = 0; r = func(1, 2); return 0;}// __attribute__((cdecl))int func(int a, int b) { int r = a + b; return r;} 编译后会产生如下代码: main函数: 12345678...1 sub $0x8, esp2 push $0x23 push $0x14 call _Z4funcii ; push eip, jmp _Z4funcii5 add $0x10,...
LeetCode刷题笔记(十三): 树
数据结构介绍:作为(单)链表的升级版,我们通常接触的树都是二叉树(binary tree),即每个节点最多有两个子节点;且除非题目说明,默认树中不存在循环结构。 代码实现:123456struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}}; 一、树的递归 题目一:二叉树的最大深度求一个二叉树的最大深度。 解答: 123456789101112class Solution {public: int maxDepth(TreeNode* root) { if (root == nullptr) return 0; int depth = 0; if (root->left != nullptr) depth =...
LeetCode刷题笔记(十二): 链表
数据结构介绍:链表是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。 代码实现:12345struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(nullptr) {}}; 补充:由于在进行链表操作时,尤其是删除节点时,经常会因为对当前节点进行操作而导致内存或指针出现问题。有两个小技巧可以解决这个问题:一是尽量处理当前节点的下一个节点而非当前节点本身,二是建立一个虚拟节点(dummy...
LeetCode刷题笔记(十一): 字符串
一、字符串比较 题目一:同构字符串判断两个字符串是否同构。同构的定义是,可以通过把一个字符串的某些相同的字符转换成另一些相同的字符,使得两个字符串相同,且两种不同的字符不能够被转换成同一种字符。 解答: 12345678910111213141516class Solution {public: bool isIsomorphic(string s, string t) { unordered_map<int, int> hashMap; unordered_map<int, int> hashMap2; int n = s.length(); for (int i = 0; i < n; ++i) { if (hashMap[s[i]] != 0 || hashMap2[t[i]] != 0) continue; hashMap[s[i]] = t[i]; hashMap2[t[i]] =...
LeetCode刷题笔记(十): 数据结构
一、数组 题目一:找到所有数组中消失的数字给定一个长度为n的数组,其中包含范围为1到n的整数,有些整数重复了多次,有些整数没有出现,求1到n中没有出现过的整数。 解答: 1234567891011121314class Solution {public: vector<int> findDisappearedNumbers(vector<int>& nums) { int n = nums.size(); vector<int> bucket(n); for (int num : nums) ++bucket[num - 1]; vector<int> res; for (int i = 0; i < n; ++i) { if (!bucket[i]) res.push_back(i + 1); } return res; ...
Spring MVC简述
一、什么是MVCMVC是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。 MVC又是属于java架构模式中的一种,粒度比设计模式(抽象工厂,单例等)更大,用来组织整个应用的分层结构,而设计模式解决的是“类/对象之间如何协作”这类微观问题。 二、Spring MVC的发展2.1 Model1时代在Model1模式下,整个web应用几乎全部用JSP页面组成,只用少量的JavaBean来处理数据库连接、访问等操作。在这个模式下JSP既是控制层(Controller)又是表现层(View)。显然,这种模式存在很多问题。比如控制逻辑和表现逻辑混杂导致代码重用率低;前后端相互依赖导致开发效率低等等。 2.2 Model2时代早期的JavaWeb MVC开发模式遵循的是“Java Bean(Model) + JSP(View) + Servlet(Controller)”这种开发模式,具体功能如下: Model: 系统涉及的数据,也就是dao和bean。 View:...
Spring AOP原理
一、定义AOP(Aspect Oriented Programming),即面向切面编程,是OOP(面向对象编程)的一种延续,二者互补。AOP的目的是将横切关注点(如日志记录、事务管理、权限控制、接口限流等)从核心业务中分离出来形成一个个切面(Aspect),通过动态管理、字节码操作等技术实现代码的复用和解耦,提高代码的可维护性和可扩展性。 二、关键术语 横切关注点(cross-cutting...










