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-26
	template<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;   1MB



memory_::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 .

...............就这样吧,有时间再继继,下次再更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值