【问题标题】:How can I call a destructor of a templated class?如何调用模板类的析构函数?
【发布时间】:2012-07-24 22:15:53
【问题描述】:

我正在使用库 Eigen 的 SparseMatrix 类。要创建一个,我使用:

typedef Eigen::SparseMatrix<float>  matrix;
matrix M (10,10);

如何调用这个对象的析构函数?

【问题讨论】:

  • @Griwes 因为我需要在循环中多次重新初始化同一个稀疏矩阵。我希望每次通过析构函数破坏矩阵都会导致最小的内存泄漏。
  • 也许您应该为此定义一个 clear() 函数 - 在明确调用析构函数之后,您的对象不再可用。 (如果你想防止内存泄漏,你也应该看看类内部)
  • @Tarek:这将导致未定义的行为。是否涉及泄漏尚未定义。

标签: c++ class destructor eigen


【解决方案1】:

你不需要。您的对象正在堆栈上创建,超出范围时将自动删除。

【讨论】:

  • 补充一点,如果你把matrix变量声明放在循环中,每次循环块存在时它都会被销毁,每次循环重复时都会发生这种情况。因此,您想要的最小内存使用量将在那里。
【解决方案2】:

你不直接调用析构函数;当此变量超出范围时将调用它。

void myFunction()
{
    matrix A (10,10);
    ... some code
    {
        matrix B (10,10);
    } // destructor of B is called here.
    ... some code
}// destructor of A is called here.

这是代码中的自动变量的行为。调用析构函数的另一种方法是,如果您使用new 动态分配对象,然后使用delete 销毁对象:

void myFunction()
{
    matrix* A = new matrix(10,10);
    ... some code
    {
        matrix* B = new matrix(10,10);
        delete B;// destructor of B is called
    }
    ... some code
    delete A;// destructor of A is called
}

【讨论】:

    【解决方案3】:

    (...) 因为我需要在循环中多次重新初始化同一个稀疏矩阵。我希望每次由其析构函数破坏矩阵将导致最小的内存泄漏。

    清晰、明显、最安全且可能最有效的解决方案是仅使用正常 C++ 语义。 “重新初始化”是通过赋值完成的。

    typedef Eigen::SparseMatrix<float>  matrix;
    matrix M (10,10);
    M = matrix(12, 12);
    

    在循环体内声明矩阵,每次循环迭代都会正确初始化和销毁​​。

    哦,假设一个没有错误的库,在所有这些情况下都有内存泄漏。只是不要乱扔news,也不要玩火(比如直接调用析构函数)。

    【讨论】:

    • 如果赋值不是最有效的,那么像 matrix(12,12).swap(M); 这样的东西在 C++03 中可能会更好(或在 C++11 中,对于尚未启用移动的类) )。您必须检查该课程的文档。由于它是一个 sparse 矩阵,因此您希望“空”矩阵能够非常快速地创建和销毁,因此 M = matrix(12,12); 的开销很小。
    【解决方案4】:

    虽然我真的不确定你为什么要这样做,但这很容易:

    M.~SparseMatrix();
    

    通常,您可以在任何类上显式调用析构函数,只需像调用任何其他函数一样调用它即可。模板类也不例外。

    【讨论】:

    • 你试过了吗?这不应该在 SparseMatrix 的成员函数之外起作用。
    • 是什么让你这么想?我的 C++ 标准副本特别声明了其他内容。 (而且,是的,我确实在 VS 2008 中尝试过)
    【解决方案5】:

    据我所知,只有一种情况需要显式调用析构函数:例如在使用placement new 时

    class Foo { /* lots of stuff here */ };
    
    char foo[sizeof(Foo)];
    new (&foo[0]) Foo();
    /* ... */
    reinterpret_cast<Foo *>(&foo[0])->~Foo();
    

    【讨论】:

      猜你喜欢
      • 2012-10-24
      • 2020-07-21
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多