Effective C++ 日积月累
1. 如何防止头疼的C++文件交叉包含。
文件夹名(或库名):
1. 每个库中有以branch_开头命名的文件和以global_开头命名的文件,且都是静态类。
2. 如果要用到所有库的功能,只需包含一个文件 global_ + 库名.h
3. 所有放入库的文件都不能包含 global_ + 库名.h。
4. global_ + 库名.h 有一个类,它是继承自所有以 branch_开头的文件中的类,这些类都是以静态成员函数构成的类。
5. global_ + 库名.h 中的命名规则为 global_库名 , branch_ + 库名.h 命名规则为: branch_库名 + name
6. 库中任何文件可以包含 branch_开头的文件,但不能包含同文件夹中以 global_开头的文件
7. 当库为层次包含关系时,列如:
std => Linux, Windows
Linux中不能包含任何 Windows 库中的文件,同时 Windows 也不能包含任何 Linux文件,但都可以包含 std 中的文件。
std 不能包含任何 Linux,Windows 中的.h文件
例如,有三个文件夹,std,Linux,Windows
branch_std_name1.h 中 不包含任何 A 中任何 .h文件
static class branch_std_name1
{
public:
static void do_something1;
};
branch_std_name2.h 中 不包含任何 A 中任何 .h文件
static class branch_std_name2
{
public:
static void do_something2;
};
global_std.h 中 可以包含任何 A 中的 .h文件
#include "branch_a_name1.h"
#include "branch_a_name2.h"
#include "mylist.h"
#include "mystring.h"
static class global_a : public branch_a_name1, branch_a_name2
{
};
static class global_b : public global_a
{
};
最后一个,为了便于书写,可以定义一个简单易记的静态类:
例:
static class ga : public global_a {}
static class gb : public global_b {}
或定义别名: typedef global_c gc;
typedef global_b gb;
最后:
最好 ga 就是全局类,是最终的命名,在任何地方都是名子 ga:: //gloabl all
基中 ga 就是包含所有的全局静态函数。
这样设计就是防止C++头疼的文件交叉包含。
2. 自定义类要尽量定义比较大小的运算符。否则使用有排序功能
的泛型类会编译出错,有时候很难排查!
例:
3. 定义一个全局内存管理类,所有 new 和 delete 都使用这个类。
例如:
memory_.h
/*******************************************************************************************
文件名 : memory_.h作者 : 李锋功能 : 内存操作创建时间 : 2016年7月6日最后一次修改时间 : 2022年09月23日
********************************************************************************************/#ifndef _MEMORY__H_
#define _MEMORY__H_#include"macro_.h"
#include <assert.h>_LF_BEGIN_//内存操作类
class memory_ {public://全局内存对象计数器static __int64 _obj_used;static __int64 _mem_used;//充许最大内存数量static int _memory_allow_max;public:memory_();~ memory_();static inline int allow_max() { return _memory_allow_max; }//内存使用量,字节static inline __int64 mem_used() { return _mem_used;}//对象使用量static inline __int64 obj_used() { return _obj_used; }public://分配内存,给对象分配内存不能用C语言的malloc函数template<typename T> static T * memNew(int nCount, bool bDefaultValue = false){//std::cout << "分配对象为:" << "T" << typeid(T).name() << "\t 个数nCount="<< nCount << "\n";if (nCount == 0) return null;if (nCount > _memory_allow_max){ throw "超出最大充许申请的对象数"; return 0; }_obj_used += nCount;_mem_used = _mem_used + sizeof(T) * nCount;if (bDefaultValue){return memory_::memset_<T>(new T[nCount], nCount, T());}else{ return new T[nCount];} }//释放内存template<typename T> static void memDelete(T *pMemory, int nCount){ _obj_used -= nCount;_mem_used -= sizeof(T) * nCount;delete[] pMemory; pMemory = null;}//设置值template<typename T> static T *memset_(T *pMem,const int nCount, const T &rDefaultValue){ assert(pMem != null);for (int n = 0; n < nCount; ++n)*(pMem + n) = rDefaultValue; return pMem;}//每一个类必须写 T& T::operator=(const T &rhs)/// <summary>/// /// </summary>/// <typeparam name="T"></typeparam>/// <param name="pDestination"></param>/// <param name="pSource"></param>/// <param name="nCount"></param>/// <returns></returns>/// 创建时间: ????-??-?? 最后一次修改时间:2021-10-26template<typename T> static T *memcpy_(T *pDestination, const T *pSource, const int nCount){ assert(nCount != 0 && pDestination != null && pSource != null); for (int n = 0; n < nCount; ++n){pDestination[n] = pSource[n]; }return pDestination;}};/// <summary>/// 内存管理,内存自动释放/// </summary>/// <typeparam name="T"></typeparam>template<typename T>class mem {private:int _nCount;public:T* data;int effectiveCount = 0; //有效数据个数const int& count() const { return _nCount; } mem(const int& nCount) {_nCount = nCount;data = memory_::memNew<T>(nCount, false);}~mem() {memory_::memDelete<T>(data, _nCount);}};_LF_END_#endif //--------------------------------------------------------------------------- !_memory__H_
memory_.cpp
#include"memory_.h"_LF_BEGIN___int64 memory_::_obj_used = 0;
__int64 memory_::_mem_used = 0;int memory_::_memory_allow_max = 1073741824; //1024 * 1024 * 1024; 1MBmemory_::memory_()
{}memory_::~memory_()
{}_LF_END_
4. 所有自定义类没有指针类数据成员,都不用定义拷贝构造函数,因为编译器会自动为你实施了最好的行为,其实根本的原因就是 memcpy 比你写的的拷贝构造函数更有效率。
例子:
对于自己定义拷贝构造
Point3d(const Point3d& p3d) {
_x = p3d._x;
_y = p3d._y;
_z = p3d._z;
}
编译提供的是 bitwise copy => memcpy(b,&a,sizeof(a));
实际上就是:
5 .
6 .
...............就这样吧,有时间再继继,下次再更新。
Effective C++ 日积月累相关推荐
- Effective C++ 50条款
Effective C++ 50条款 条款 1:尽量用 const 和 inline 而不用#define--尽量用编译器而不用预处理 #define max(a,b) ((a) > (b) ? ...
- [.NET] 《Effective C#》快速笔记 - C# 中的动态编程
<Effective C#>快速笔记 - C# 中的动态编程 静态类型和动态类型各有所长,静态类型能够让编译器帮你找出更多的错误,因为编译器能够在编译时进行大部分的检查工作.C# 是一种静 ...
- Effective STL 50条有效使用STL的经验笔记
Scott Meyers大师Effective三部曲:Effective C++.More Effective C++.Effective STL,这三本书出版已很多年,后来又出版了Effective ...
- 《Effective C++》第8章 定制new和delete-读书笔记
章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...
- VirtualBox: Effective UID is not root
为什么80%的码农都做不了架构师?>>> 桌面上运行virtualbox出错: The virtual machine 'xp' has terminated unexpect ...
- Effective Java:对于全部对象都通用的方法
前言: 读这本书第1条规则的时候就感觉到这是一本非常好的书.可以把我们的Java功底提升一个档次,我还是比較推荐的.这里我主要就关于覆盖equals.hashCode和toString方法来做一个笔记 ...
- 第 3 次读 Effective Java,这 58 个技巧最值!
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:Dong GuoChao <Effective ...
- 日积月累真的很可怕,记住这些编程单词,两周学会敲代码
刚开始学习Python能记住下面这些单词,就够了,一天学习记个九.十个单词,在配合些基础入门的视频.书籍等等方法去学习加深印象,比那些死记硬背要好很多. 下列是编程常用单词,有些小伙伴英语不好的,我还 ...
- Effective C++ 类与函数设计和申明
Effective C++ 类与函数的设计和申明 在看<Effective C++>这本书的过程中,我无数次的发出感叹,这他妈写得太好了,句句一针见血,直接说到点上.所以决定把这本书的内容 ...
最新文章
- 记录一次简单、高效、无错误的linux上安装pytorch的过程
- 【MATLAB】稀疏矩阵(含有大量0元素的矩阵)
- 英特尔媒体年会场景(15P)——实拍与小结
- hibernate之关联关系(一对多)
- Leet Code OJ 168. Excel Sheet Column Title [Difficulty: Easy]
- (转)编码剖析Spring依赖注入的原理
- 微软发布紧急更新,修复了多个 Windows Server 身份验证问题
- PIE SDK组件式开发综合运用示例
- engine.POST()处理POST请求
- 【HAVENT原创】Salesforce (JSforce) 调用示例
- 2017年10月30日360最新虚拟壳脱壳后完全修复
- Linux系统下KVM虚拟机的基本管理和操作
- Win10无法访问移动硬盘怎么解决
- SQL多对多关系通过关联中间表查询
- 面向对象设计的23种设计模式
- 京东API接口:item_get - 获得JD商品详情
- d va爬黑板animate_部编版四年级语文上册第17课爬天都峰微课视频|MP3朗读|同步练习...
- 【黑金动力社区】【531体验板教程】 第三章 开发环境(三)
- 2022年团体程序设计天梯赛C++个人题解附带解题思路
- oracle all_tab_columns,[20120507]视图all_tab_columns的定义问题.txt