C ++:从函数返回一个Class对象

时间:2016-05-05 12:43:34

标签: c++ class memory memory-leaks

我在Stackoverlow上阅读了一些关于此问题的文章How to “return an object” in C++?,但我的问题仍然存在。

我的程序实现了Vector Class(Maths中的向量)。我想重载一个运算符+,我尝试修改函数中的空对象或使用静态成员,结果在我对下面这些代码的评论中。

这是我的代码:

#include <iostream>

class Vector {
    double * arr;
    unsigned short dim;

public:
    Vector(const int& d = 0); // This constructor initialize memory for its member

    Vector& operator = (const Vector& v);

    /* This function must return a Vector object
     *
     * Example: Vector v = v1 + v2; // v1.arr = {1, 1, 3}, v2.arr = {1, 0, 1}
     *
     * Then v.arr = {2, 1, 4} // this is just an example

     * When I run it by using empty class like:
     * Vector operator + (const Vector& v) const {
     *     Vector vec();
     *     // Do something with vec;
     *     return vec;
     * }
     * It returns a garbage value.
     *
     * When I run the code below, the GNU compiler inform:
     * C:\Desktop>g++ -Wall -ansi -c Vector.cpp
     * C:\Desktop>g++ -Wall -ansi -o main.exe main.cpp vector.o
     * vector.o:Vector.cpp:(.text+0x33e): undefined reference to `Vector::_vec'
     */

    Vector operator + (const Vector& v) const {

        if (dim == v.dim) {
            _vec = Vector(dim);

            for (int i = 0; i < dim; ++i) {
                _vec.arr[i] = arr[i] + v.arr[i];
            }

            return _vec;
        }

        return Vector(0);
    } 

    ~Vector();

private:
    static Vector _vec;
};

任何人都需要它的主要功能:

#include <iostream>
#include "Vector.h"

using namespace std;

int main(int argc, char const *argv[]) {
    Vector v(-2), v3;
    Vector v2(2);

    cout << "Input vector: ";
    cin >> v;
    cout << v << endl;
    cout << "Input vector: ";
    cin >> v2;
    cout << v2 << endl;

    v3 = v + v2;
    cout << v3;

    return 0;
}

感谢阅读。

3 个答案:

答案 0 :(得分:2)

我认为它意味着是常规的双向矢量(或者更像是数组,因为你还没有改变大小)。而operator +是成员添加两个向量。

示例中有很多乞丐错误,所以让我们先让你加速:

  1. 除了intdoublecharsize_t之外,不要使用其他原始类型(没有充分的理由)(就像使用短片一样)。
  2. 不要混用signedunsigned(与dimd一样)并且不要混用类型(与{{1}一样) }和i)没有充分的理由。
  3. 不要通过const引用传递原始类型(就像使用dim
  4. 一样
  5. 最好将构造函数initializer list用于简单的事情,而不是在构造函数体中初始化
  6. const int& d不能小于unsigned,因此0是多余的。
  7. 您可以将if (dim < 0)甚至1传递给0,因此new[]条件基本上是多余的
  8. 你必须if你借来的记忆。析构函数将是一个很好的地方。
  9. BTW你声明但没有定义你的析构函数。
  10. 就我所见,delete[]绝对没有商务。
  11. 喔。不要通过静态向量返回。创建一个新的:static Vector _vec;并返回。
  12. UPDATE1:

    1. Vector resultV(dim);会返回一些邪恶的内容,因为你没有关注2.很可能会返回Vector(-2)
    2. 要从Vector(USHORT_MAX - 2)获取并从cin打印,您需要重载coutistream& operator>>( istream&, Vector )
    3. 应用这些内容,如果问题仍然存在,请相应地修改问题。

答案 1 :(得分:1)

对于您当前的问题,您声明静态成员但不在任何地方分配内存。

你需要

Vector Vecor::_vec;

在其中一个.cpp文件中。

此外,依靠静态变量返回操作的结果是一个坏主意。更好地研究移动语义。

答案 2 :(得分:1)

我分析了你的问题并发现了以下问题:

一般错误:

  • 您错过了宣布复制构造函数。
  • 您错过了声明访问矢量值的函​​数(operator[])。

构造函数Vector(const int& d = 0)

  • 通过const引用传递一个int没有错,但没用。
  • if (dim == 1)案例错误:您无法使用相同的指针变量来存储double和double []

方法Vector& operator=(const Vector& v)

  • 它不处理案例dim = 0dim = 1(无论如何案例dim = 1在构造函数中也是错误的,并且不需要单独处理)。

方法Vector operator+(const Vector& v) const

  • 这里不需要使用静态变量。可能你得到的错误是构造函数中的错误的结果。

析构函数~Vector();

  • 缺少实现:它应该释放由其他函数分配的动态内存

这是正确的代码:

#include <iostream>

class Vector 
{
    double* arr;
    int     dim;

public:

    Vector(int d = 0) 
    {
        if(dim < 0)
        {
            std::cout << "Dimension could not less than 0. It will be set to 0." << std::endl;
            // Better to throw an exception here!
        }

        if(dim <= 0) 
        {

            dim = 0;
            arr = NULL;
        }
        else
        {
            dim = d;
            arr = new double[dim];
        }
    } 

    const double& operator[](int i) const 
    {
        return arr[i]; 
    }

    double& operator[](int i) 
    {
        return arr[i]; 
    }

    Vector(const Vector& v)
    {
        dim = v.dim;

        if(dim > 0)
        {
            arr = new double[dim];

            for(int i = 0; i < dim; ++i) 
            {
                arr[i] = v.arr[i];
            }
        }
    }

    Vector& operator=(const Vector& v) 
    {
        if(this != &v) 
        {
            delete[] arr;

            dim = v.dim;

            if(dim > 0)
            {
                arr = new double[dim];

                for(int i = 0; i < dim; ++i) 
                {
                    arr[i] = v.arr[i];
                }
            }
        }

        return *this;
    }

    Vector operator+(const Vector& v) const 
    {
        if(dim == v.dim) 
        {
            Vector r(dim);

            for(int i = 0; i < dim; ++i) 
            {
                r.arr[i] = arr[i] + v.arr[i];
            }

            return r;
        }

        return Vector(0); // Better to throw an exception here!
    } 

    ~Vector()
    {
        if(arr != NULL) delete[] arr;
    }
};

void main()
{
    Vector v1(3);
    Vector v2(3);

    v1[0] = 1;
    v1[1] = 2;
    v1[2] = 3;

    v2[0] = 2;
    v2[1] = 4;
    v2[2] = 6;

    Vector v3 = v1 + v2;

    std::cout << std::endl << v3[0];
    std::cout << std::endl << v3[1];
    std::cout << std::endl << v3[2];
    std::cout << std::endl;
}

主函数产生输出:

3
6
9