C++中遇到的_CrtlsValidHeapPointer(block)错误引发的思考

在这里插入图片描述
肇事的代码在此:

#include<iostream>
#include<string>
using namespace std;

class Operation
{
public:
	Operation() :num1(0), num2(0) {}
	void setnum1(double num1)
	{
		this->num1 = num1;
	}

	Operation(double num1, double num2) :num1(num1), num2(num2) {}
	void setnum2(double num2)
	{
		this->num2 = num2;
	}

	double getnum1()
	{
		return num1;
	}

	double getnum2()
	{
		return num2;
	}

	virtual double getResult()
	{
		return 0;
	}

protected:
	double num1;
	double num2;
};

class OperationAdd : virtual public Operation
{
public:
	OperationAdd(double num1, double num2) :Operation(num1, num2) {}
	double getResult()
	{
		double result = 0;
		result = num1 + num2;
		return result;
	}
};

class OperationSub : virtual public Operation
{
public:
	OperationSub(double num1, double num2) : Operation(num1, num2) {}
	double getResult()
	{
		return num1 - num2;
	}
};

class OperationMul : virtual public Operation
{
public:
	OperationMul(double num1, double num2) : Operation(num1, num2) {}
	double getResult()
	{
		return num1 * num2;
	}
};

class OperationDiv : virtual public Operation
{
public:
	OperationDiv(double num1, double num2) : Operation(num1, num2) {}
	double getResult()
	{
		if (num2 == 0)
		{
			cout << "除数不能为0!" << endl;
			return 0;
		}
		return num1 / num2;
	}
};

class OperationFactory
{
public:
	OperationFactory() {}
	Operation* createoperation(double num1, double num2, char operate)
	{
		switch (operate)
		{
		case'+':
			oper = new OperationAdd(num1, num2);
			break;

		case'-':
			oper = new OperationSub(num1, num2);
			break;

		case'*':
			oper = new OperationMul(num1, num2);
			break;

		case'/':
			oper = new OperationDiv(num1, num2);
			break;

		default:
			break;
		}
		return oper;
	}

	 ~OperationFactory()
	{
		if (oper != nullptr)
		{
			std::cout << "delete oper" << std::endl;
			delete oper;
		}
	}

private:
	Operation* oper = nullptr;
};

int main()
{
	{
		cout << "请输入进行的运算:+、-、*、/" << endl;
		char operate;
		cin >> operate;
		cout << "请输入两个数值:" << endl;
		double num1, num2;
		cin >> num1 >> num2;

		OperationFactory of;
		double  result;
		result = of.createoperation(num1, num2, operate)->getResult();
		cout << "运算结果为:" << result << endl;

	}
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述
内存肯定是出错了,定位在~OperationFactory()中,如果这里的delete操作不执行,就不会报错,但是指针oper指向的对象就不能释放了。
发现个问题,就是这段代码的基类的析构函数没有写,而是用编译器添加的默认析构函数,会不会是它的原因呢?
只需要加一行代码:

class Operation
{
public:
	Operation() :num1(0), num2(0) {}
	virtual ~Operation() {} //加的代码,需要为虚析构函数
	...
};

运行结果:

请输入进行的运算:+-*/
+
请输入两个数值:
1
2
运算结果为:3
delete oper
请按任意键继续. . .

这时候不报错了,内存也正确释放了。

当基类的析构函数为虚析构函数时,子类的析构函数就自然而然的是虚析构函数,不管前面有没有virtual,或者override(建议还是加上override,C++11开始的,否则会有警告)。

参考:
c++设计模式—简单工厂模式

C++中的虚析构函数

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值