首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何手动删除类的实例?

如何手动删除类的实例?
EN

Stack Overflow用户
提问于 2016-03-24 10:55:50
回答 6查看 38.8K关注 0票数 6

如何手动删除类的实例?

示例:

代码语言:javascript
复制
#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;
}
EN

回答 6

Stack Overflow用户

发布于 2016-03-24 11:04:21

在不知道用例或你想要解决的实际问题的情况下(请阅读the XY problem,你的问题就是一个很好的例子),最简单的方法就是重新分配:

代码语言:javascript
复制
Cheese swiss("Jarlsberg", 4.99);
...
swiss = Cheese("Gruyère",5.99);

当然,这可能需要您实现一个赋值运算符,但是在rules of three or five之后,您无论如何都应该这样做(但是如果您遵循the rule of zero,则不需要赋值运算符)。

如果您明确希望销毁当前的swiss对象,也可以使用指针:

代码语言:javascript
复制
Cheese* swiss = new Cheese("Jarlsberg", 4.99);
...
delete swiss;
swiss = new Cheese("Gruyère",5.99);

但是指针是一个蠕虫罐头,你应该避免,并且在现代C++中并不需要太多。但是,如果您想要多态性,则需要指针(或引用)。然后你可以有一个指向基类的指针,指向实际的实例,像虚函数这样的东西就会像预期的那样工作。

此外,根据我们仍然一无所知的情况,您当然可以使用作用域:

代码语言:javascript
复制
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对象将在作用域结束时被析构,就像任何其他嵌套作用域变量被析构和“消失”一样。

票数 12
EN

Stack Overflow用户

发布于 2016-03-24 11:02:55

可以使用作用域来允许您定义类的另一个实例。

代码语言:javascript
复制
Cheese swiss("Toe", 3.14)

{
    Cheese swiss("Ear", 15.9);
}

一般来说,本地声明的实例在超出范围时会自行销毁。

如果你真的满足了销毁奶酪的需求,那么你需要动态分配它。

代码语言:javascript
复制
  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.

必须始终手动删除动态分配的内存。

票数 5
EN

Stack Overflow用户

发布于 2016-03-24 11:19:06

在极少数情况下,您需要这样做。但您可能会在创建抽象数据类型时遇到这种情况。

例如,如果您正在创建一个变体类型,您可能希望设置一个对齐的数据类型,然后手动放置new和delete。

代码语言:javascript
复制
typename std::aligned_union<0, FirstType, RestTypes...>::type m_buffer;

为了生动地描述:

代码语言:javascript
复制
new (&m_buffer) AssignType(forward<T>(x));

要清除,请执行以下操作:

代码语言:javascript
复制
(HeldType*)(&m_buffer)->~HeldType();

然而,正如在众多其他帖子中提到的那样。如果您正在正常编程,那么您不需要担心手动调用dtors。如果它在堆栈上,那么它会为您清除。如果它在堆上,那么delete将为您处理它。唯一需要这样做的时候就是手动控制对象生存期的时候,而这样做的主要原因是在实现抽象数据类型时。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36192499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档