【问题标题】:Destructor called after returning from function从函数返回后调用的析构函数
【发布时间】:2015-04-18 19:51:51
【问题描述】:

我的大学有一些项目,我需要将一些数据从文件转换为矩阵表示。

主要问题是在返回表单“returnNeighbours(int node)”后,在邻居对象上调用了析构函数(正如我从运行 gdb 得出的结论)。

我知道在函数中初始化局部变量时总是调用析构函数,但 neihbours 是类成员。我不会发布所有内容,因为我认为没有必要。下面列出了一些结构。

representation.cpp

NodeContainer::NodeContainer(){ size = 0; array = nullptr; }
NodeContainer::~NodeContainer(){ size = 0; delete[] array; }
void NodeContainer::allocateMemoryAndSetSize(int n){ size = n; array = new int[size]; }

void MatrixRep::convertDataToMatrixRep(int** array)
{
  for(int i = 0 ; i != size; i++)
    for(int j = 0; j != size; j++)
        matrix[i][j] = array[i][j];
}

NodeContainer MatrixRep::returnNeighbours(int node)
{
    deleteNeighboursIfAny();
    if(!checkIfNotBeyondMatrix(node))
        return neighbours;

    neighbours.allocateMemoryAndSetSize(countNeighbours(node));

    for(int i = 0, j = 0; i < size; i++)
        if(matrix[node-1][i] != 0)
        {
            neighbours.array[j] = matrix[node-1][i];
            j++;
        }
    return neighbours;
}

void MatrixRep::deleteNeighboursIfAny(){ if(neighbours.array) neighbours.~NodeContainer(); }

bool MatrixRep::checkIfNotBeyondMatrix(int node)
{
    if(node == 0 || node > size)
    {
        std::cerr<<"There is no such a node!\n";
        return false;
    }
    else
        return true;
}

int MatrixRep::countNeighbours(int node)
{
    int count_non_zero = 0;

    for(int i = 0; i != size; i++)
        if(matrix[node-1][i] != 0)
            count_non_zero++;
    return count_non_zero;
}

representation.h

struct NodeContainer
{
    int size;
    int* array;

    NodeContainer();
    ~NodeContainer();
    void allocateMemoryAndSetSize(int);
};  

class MatrixRep
{
    int size;
    NodeContainer neighbours;
    int** matrix;

    public:

    MatrixRep(int);
    ~MatrixRep();
    void convertDataToMatrixRep(int**);
    NodeContainer returnNeighbours(int);
    void deleteNeighboursIfAny();
    bool checkIfNotBeyondMatrix(int);
    int countNeighbours(int);
    void setupMatrix();
    void deleteMatrix();
};      

【问题讨论】:

  • 你真的存储了调用returnNeighbours的结果吗?
  • 是的,我正在测试 main.cpp 中存储
  • 嗯,它返回按值,这意味着为返回创建了一个新对象,并且该对象当然必须被破坏。
  • 好的,先生,您有什么建议?我应该通过引用退回它吗?
  • 首先,你不应该有多个语句的单行。其次,你不应该为超过一行的代码省略花括号,也就是在你的返回邻居函数中。

标签: c++ function destructor


【解决方案1】:

如果您想返回 NodeContainer 的副本,您必须为它实现一个复制构造函数和赋值运算符。如果您使用的是符合 C++11 的编译器,那么还可以实现移动构造函数和移动赋值运算符。

另一方面,如果您不想创建副本,则必须返回成员的指针或引用。您还可以将成员设为 std::shared_ptr,在这种情况下您可以返回。

但是,在您当前的实现中,您实际上返回的是 NodeContainer 的 副本。一旦你的副本超出范围,它的析构函数就会被调用,它会释放它的内存,在这种情况下,它是你成员的原始内存,实际上使你的成员无效。实施并不像现在这样好。因此,根据您的目标,要么实施第一个建议的解决方案,要么实施第二个。

【讨论】:

  • 这对我帮助很大。谢谢你的回答!
猜你喜欢
  • 1970-01-01
  • 2015-05-02
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-19
  • 2019-10-28
  • 2016-09-21
  • 1970-01-01
相关资源
最近更新 更多