返回地址或局部变量或临时C ++警告

时间:2010-10-06 08:24:01

标签: c++ warnings

  

可能重复:
  c++ warning: address of local variable

您好, 当我写这段代码时:

//Returns the transpose matrix of this one
SparseMatrix& SparseMatrix::transpose()const{
    vector<Element> result;
    size_t i;
    for(i=0;i<_matrix.size();++i){
        result.push_back(Element(_matrix.at(i)._col, _matrix.at(i)._row, _matrix.at(i)._val));
    }

    return SparseMatrix(numCol,numRow,result);
}

我收到警告“返回地址或本地变量或临时”。最后一行调用SparseMatrix构造函数。我不明白这段代码有什么问题,我怎么能解决它,所以我可以按照自己的意愿返回一个SparseMatrix对象。

3 个答案:

答案 0 :(得分:13)

您正在返回引用,而不是实际对象 - 请注意&此处:

SparseMatrix& SparseMatrix::transpose()const{

如果要返回实际对象,请删除&

最后一行确实调用了构造函数,但它不返回结果对象。该对象立即被销毁,并返回对它的无效引用。

答案 1 :(得分:11)

在C ++中,当超出范围时,局部变量被“自动”破坏。您的return语句将创建一个名为SparseMatrix的无名临时变量,该变量将立即超出范围。因此,返回对它的引用是没有意义的。

按值返回可能更容易:然后将返回临时副本。编译器可以优化它(复制省略)。

如果你真的想要从一个函数中传递一个对象,你应该使用new在堆上创建它:

SparseMatrix* SparseMartix::transopse()const{


     //...
     return new SparseMatrix(...);

}

但是,你需要自己处理返回对象的生命周期。

答案 2 :(得分:0)

构造'T()'创建一个临时类型'T',它基本上不是Lvalue(但是Rvalue)。

  

$ 12.1 / 11 - “功能表示法类型   转换(5.2.3)可用于   创建其类型的新对象。 [   注意:语法看起来像   显式调用构造函数。

     

12以这种方式创建的对象未命名。 [注意:12.2描述了&gt;临时对象的生命周期。 -结束   注意] [注意:显式构造函数调用不会产生左值,见3.10。 - 尾注]   这个临时的生命周期是完整表达式的结束,即表达式之后的结束分号。

     

$ 12.2 / 3 - “临时物品是   作为最后一步被摧毁   评估全表达式(1.9)   那个(词汇上)包含了这一点   它们的创建地点。这是真的   即使评估结束了   抛出一个例外。价值   计算和副作用   摧毁一个临时物体   仅与...相关联   完整表达,而不是任何具体的   子表达式“。

     

$ 12.2 / 5-'临时的一生   绑定到a中的返回值   函数返回语句(6.6.3)是   没有延长;暂时的是   在结束时被摧毁   回归中的完整表达   语句“。

因此,您的函数会尝试返回对存储持续时间已经结束并且对象已被销毁的内存位置的引用。

因此发出警告。请注意,标准不需要明确诊断出这种情况,因此需要警告。