如何手动删除类的实例?
示例:
#include <iostream>
#include <cstring>
class Cheese {
private:
string brand;
float cost;
public:
Cheese(); // Default constructor
Cheese(string brand, float cost); // Parametrized constructor
Cheese(const Cheese & rhs); // Copy construtor
~Cheese(); // Destructor
// etc... other useful stuff follows
}
int main() {
Cheese cheddar("Cabot Clothbound", 8.99);
Cheese swiss("Jarlsberg", 4.99);
whack swiss;
// fairly certain that "whack" is not a keyword,
// but I am trying to make a point. Trash this instance!
Cheese swiss("Gruyère",5.99);
// re-instantiate swiss
cout << "\n\n";
return 0;
}发布于 2016-03-24 11:04:21
在不知道用例或你想要解决的实际问题的情况下(请阅读the XY problem,你的问题就是一个很好的例子),最简单的方法就是重新分配:
Cheese swiss("Jarlsberg", 4.99);
...
swiss = Cheese("Gruyère",5.99);当然,这可能需要您实现一个赋值运算符,但是在rules of three or five之后,您无论如何都应该这样做(但是如果您遵循the rule of zero,则不需要赋值运算符)。
如果您明确希望销毁当前的swiss对象,也可以使用指针:
Cheese* swiss = new Cheese("Jarlsberg", 4.99);
...
delete swiss;
swiss = new Cheese("Gruyère",5.99);但是指针是一个蠕虫罐头,你应该避免,并且在现代C++中并不需要太多。但是,如果您想要多态性,则需要指针(或引用)。然后你可以有一个指向基类的指针,指向实际的实例,像虚函数这样的东西就会像预期的那样工作。
此外,根据我们仍然一无所知的情况,您当然可以使用作用域:
Cheese swiss("Jarlsberg", 4.99);
...
{
Cheese swiss("Gruyère",5.99);
// In here the swiss cheese is a Gruyère
...
}
// Out here the swiss cheese is a Jarlsberg虽然像这样隐藏变量名是可行的,但这是一个您应该避免的坏习惯,因为它会给代码的读者带来混乱。另一方面,即使在使用作用域时,也不会阻止您使用所需的任何(有效)变量名,因此您可以将外部作用域实例命名为jarlsberg,将内部作用域实例命名为gruyere,然后gruyere对象将在作用域结束时被析构,就像任何其他嵌套作用域变量被析构和“消失”一样。
发布于 2016-03-24 11:02:55
可以使用作用域来允许您定义类的另一个实例。
Cheese swiss("Toe", 3.14)
{
Cheese swiss("Ear", 15.9);
}一般来说,本地声明的实例在超出范围时会自行销毁。
如果你真的满足了销毁奶酪的需求,那么你需要动态分配它。
Cheese *swiss = new Cheese("toe", 3);
// do something with swiss.
delete swiss; // throw it away.
swiss = new Cheese("Ear", 7);
// do something with swiss.
delete swiss; // throw it away.必须始终手动删除动态分配的内存。
发布于 2016-03-24 11:19:06
在极少数情况下,您需要这样做。但您可能会在创建抽象数据类型时遇到这种情况。
例如,如果您正在创建一个变体类型,您可能希望设置一个对齐的数据类型,然后手动放置new和delete。
typename std::aligned_union<0, FirstType, RestTypes...>::type m_buffer;为了生动地描述:
new (&m_buffer) AssignType(forward<T>(x));要清除,请执行以下操作:
(HeldType*)(&m_buffer)->~HeldType();然而,正如在众多其他帖子中提到的那样。如果您正在正常编程,那么您不需要担心手动调用dtors。如果它在堆栈上,那么它会为您清除。如果它在堆上,那么delete将为您处理它。唯一需要这样做的时候就是手动控制对象生存期的时候,而这样做的主要原因是在实现抽象数据类型时。
https://stackoverflow.com/questions/36192499
复制相似问题