下面代码谁能帮我解释一下?

base1 和 base2

class base1
{
public: 
  virtual  ~base1(){
        cout << "~base1()" << "\n";
    }
};

class base2 : public base1
{
public:
    virtual ~base2() {
        cout << "~base2()" << "\n";
    }
};

_AnyHelper  与 _AnyHelperBase

	class _AnyHelperBase
	{
	public: 
		virtual const std::type_info& Type()const = 0; // { return typeid(nullptr); }
		virtual _AnyHelperBase* Clone() const = 0; //{ return nullptr; }
		virtual bool Equal(const _any& r)const = 0; // { return false; }
		virtual void* GetDataPointer()const = 0; // return null; } 
		virtual bool IsArray()const = 0;
	};

	template<typename T>
	class _AnyHelper :public _AnyHelperBase
	{
	public:
		/// <summary>
		/// 用数组来保存T类型数据,如果是单个T类型数据,数据就是 _data[0],
		/// 否则是 _data.GetDataPointer(),如字符串。
		/// </summary>
		lf::_Array<T> _data;
		 
	public: //-------------------------------构造
		_AnyHelper(const T* pt, const size_t& nCount) {
			_data.SetBuffer(nCount + 1);
			_data.Add(pt, nCount);
			_data.ZeroBufferAll();
		}

		/// <summary>
		/// 拷贝构造
		/// </summary>
		/// <param name="r"></param>
		_AnyHelper(const _AnyHelper& r) {
			_data = r._data;
		}
		
		_AnyHelper() {}

	public: //-----------------------------------重写
		virtual const std::type_info& Type()const override
		{
			return typeid(T);
		}

		/// <summary>
		/// 返回一个新的对象指针
		/// </summary>
		/// <returns></returns>
		virtual _AnyHelper* Clone()const override
		{
			//见ClearMemory()
			//return m.NewEmplace<_AnyHelper<T>>(*this);
			return new _AnyHelper(*this);
		}



		/// <summary>
		/// 原则:
		///		相同数据才判断是否相等
		/// 
		/// </summary>
		/// <param name="r"></param>
		/// <returns></returns>
		/// 创建时间: 2024-11-23      最后一次修改时间:2024-11-23
		virtual bool Equal(const _any& r)const override{
			if (Type() == r._pData->Type()) { 
				return  _data == ((_AnyHelper<T>*)r._pData)->_data;
			} 
			return false;
		}

		virtual void* GetDataPointer()const override {
			if (_data.size() == 0)
				return nullptr;
			else if (_data.size() == 1)
				return &_data[0];
			else
				return _data.DataPointer();
		}

		virtual bool IsArray()const override {
			return _data.size() > 1;
		}

	public: //-----------------------------------------运算符重载
		 
	};

可以运行

    //下面代码可以运行
    auto p2 = new _any::_AnyHelper<int>[1];
    auto p1 = p2;
    delete[] p1;
 

可以执行

    //下面代码可以运行
    auto p2 = new base2[1];
    auto p1 = p2;
    delete[] p1;

可以执行:


    //下面代码可以运行
    auto p2 = new base2[1];
    base1* p1 = p2;
    delete[] p1;

不能执行

    //下面代码不可以运行
    auto p2 = new _any::_AnyHelper<int>[1];
    _any::_AnyHelperBase* p1 = p2;
    delete[] p1;

base1 是 base2的基类,_AnyHelperBase也是_AnyHelper<int> 的基类,为什么结果却不同?

解决了,是因为_AnyHelperBase和_AnyHelper没有加上析构函数:

在_AnyHelperBase中


//一定要加上析构函数
virtual ~_AnyHelperBase(){}

在_AnyHelper中
 

//一定要加上析构函数
virtual ~_AnyHelper() {	}

现在可以了:

为什么要有delete[],因为我要用上自己的内存管理函数:

/// <summary>
/// 直接构建一个新的MyClass,并返回它的一个指针。(好处免去初始化)
/// 用法例子:
///
/// list<int>* pl = NewEmplace<list<int>>(5,10); //申请一个列表内存指针(5个元素都是10的列表)
/// delete[] pl; //删除内存对象,分配时用new[]分配的
/// </summary>
/// <typeparam name="MyClass"></typeparam>
/// <typeparam name="...MyClassConstructorParameterTypes"></typeparam>
/// <param name="...MyClassConstructorParameters"></param>
/// <returns></returns>
/// 创建时间: 2024-10-01      最后一次修改时间:2024-10-01
template<typename MyClass, typename... MyClassConstructorParameterTypes>
static  MyClass* NewEmplace(MyClassConstructorParameterTypes&&... MyClassConstructorParameters)
{
	_obj_used += 1;
	_mem_used = _mem_used + sizeof(MyClass);


	/*
	//不能用 delete[] 删除
	return new MyClass(
		std::forward<MyClassConstructorParameterTypes>(MyClassConstructorParameters)...);

	*/

	/*
	list<int> il = { 1,2,3 };
	std::list<int>* p2 = new std::list<int>[1] {il};
	*/

	//delete[] pl; //删除内存对象,分配时用new[]分配的
	return new MyClass[1]
	{
		MyClass(
		std::forward<MyClassConstructorParameterTypes>(MyClassConstructorParameters)...) 
	};

}

/// <summary>
/// 功能:释放内存,并把内存指针重置为0
/// 
/// 条款3:尽量以 new 和 delete 取代malloc 和 free
///		分配内存,给对象分配内存不能用C语言的malloc函数, 因为 malloc函数不会调用用对象的
///		构造函数,free函数不会调用对象的析构函数。	  
/// 条款5:使用相同形式的 new 和 delete
///		游戏规则:如果你在调用 new 时使用了 [ ] ,则你必须在调用 delete 时也使用[] 。
///		如果你在调用 new 的时候没有使用[],那么你也不应该在调用 delete 时使用[] 。
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="pMemory"></param>
/// <param name="nCount"></param>
/// 创建时间:????-??-??    最后一次修改时间:2024-11-29
template<typename T> static  void Delete(T*  &pMemory, int  nCount)
{ 
	_obj_used -= nCount;
	_mem_used -= sizeof(T) * nCount;
	delete[] pMemory;	
	pMemory = null;
}

/// <summary>
/// 功能:分配内存。
/// 
/// 条款3:尽量以 new 和 delete 取代malloc 和 free
///		分配内存,给对象分配内存不能用C语言的malloc函数, 因为 malloc函数不会调用用对象的
///		构造函数,free函数不会调用对象的析构函数。	  
/// 条款5:使用相同形式的 new 和 delete
///		游戏规则:如果你在调用 new 时使用了 [ ] ,则你必须在调用 delete 时也使用[] 。
///		如果你在调用 new 的时候没有使用[],那么你也不应该在调用 delete 时使用[] 。
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="nCount">分配个数</param>
/// <returns></returns>
/// 创建时间: ????-??-??      最后一次修改时间:2024-12-08
template<typename T> static  T  * New(const int&  nCount, const bool& bZero = false)
{
	//std::cout << "分配对象为:" << "T" << typeid(T).name() << "\t 个数nCount="<< nCount << "\n";
	 
	if (nCount <= 0)  return null;
	 
	if (nCount > _memory_allow_max)
	{ 
		throw "超出最大充许申请的对象数"; 
	}

	 
	_obj_used += nCount;
	_mem_used = _mem_used + sizeof(T) * nCount;
	
	/*
	if (bZero) //初始化内存为0
	{
		T* pt = new T[nCount];
		for (int i = 0; i < nCount; ++i)
		{
			pt[i] = T();
		}

		return pt;
	}
	else
	{
		return  new T[nCount];
	}
	*/

	/*
	int (*pia = new int[10];  		//10个未初始化的int

	int *pia2 = new int [10]();  	 //10个值初始化为0的int

	string *psa = new string[10];  	//10个空string
	string *ps2 = new string[10](); //10个空string


	*/
	if (bZero) {
		return new T[nCount]();	
	}else {
		return new T[nCount];
	}		
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值