C++ C++;:从函数返回类对象

C++ C++;:从函数返回类对象,c++,class,memory,memory-leaks,C++,Class,Memory,Memory Leaks,我在Stackoverlow上读过一些关于这个问题的文章,但我的问题仍然存在 我的程序实现了一个向量类(数学中的向量)。我想重载一个操作符+,我试图修改函数中的空对象或使用静态成员,结果在下面我对这些代码的注释中 这是我的代码: #include <iostream> class Vector { double * arr; unsigned short dim; public: Vector(const int& d = 0); // This

我在Stackoverlow上读过一些关于这个问题的文章,但我的问题仍然存在

我的程序实现了一个向量类(数学中的向量)。我想重载一个操作符
+
,我试图修改函数中的空对象或使用静态成员,结果在下面我对这些代码的注释中

这是我的代码:

#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;
};
#包括
类向量{
双*arr;
无符号短dim;
公众:
Vector(const int&d=0);//此构造函数初始化其成员的内存
向量和运算符=(常量向量和v);
/*此函数必须返回向量对象
*
*示例:Vector v=v1+v2;//v1.arr={1,1,3},v2.arr={1,0,1}
*
*那么v.arr={2,1,4}//这只是一个例子
*当我使用空类运行它时,如:
*向量运算符+(常量向量和v)常量{
*向量向量向量();
*//用vec做点什么;
*返回向量;
* }
*它返回一个垃圾值。
*
*当我运行下面的代码时,GNU编译器会通知:
*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):对“vector::_vec”的未定义引用
*/
向量运算符+(常量向量和v)常量{
if(dim==v.dim){
_向量=向量(dim);
对于(int i=0;i
任何需要它的人的主要功能:

#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;
}
#包括
#包括“Vector.h”
使用名称空间std;
int main(int argc,char const*argv[]{
向量v(-2),v3;
矢量v2(2);
cout>v;

cout对于眼前的问题,您声明了静态成员,但没有将其内存分配到任何位置

你需要有

Vector Vecor::_vec;
在其中一个.cpp文件中


另外,依赖静态变量从操作返回结果是一个坏主意。最好研究一下移动语义。

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

你需要有

Vector Vecor::_vec;
在其中一个.cpp文件中


另外,依赖静态变量从操作返回结果是一个坏主意。最好研究一下移动语义。

我分析了您的coud,发现了以下问题:

一般错误:

  • 您没有声明副本构造函数
  • 您没有声明用于访问向量值的函数(
    运算符[]
构造函数
向量(const int&d=0)

  • 通过常量引用传递int不是错误的,而是无用的
  • if(dim==1)
的大小写是错误的:不能使用同一指针变量来存储double和double[] 方法
向量和运算符=(常量向量和v)

  • 它不处理案例
    dim=0
    dim=1
    (无论如何,案例
    dim=1
    在构造函数中也是错误的,不需要单独处理)
方法
Vector操作符+(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;
}

我分析了你的简历,发现了以下问题:

一般错误:

  • 您没有声明副本构造函数
  • 您没有声明用于访问向量值的函数(
    运算符[]
构造函数
向量(const int&d=0)

  • 通过常量引用传递int不是错误的,而是无用的
  • if(dim==1)的大小写是错误的:不能使用同一指针变量来存储double和double[]
方法
向量和运算符=(常量向量和v)

  • 它不处理案例
    dim=0
    dim=1
    (无论如何,案例
    dim=1
    在构造函数中也是错误的,不需要单独处理)
方法
Vector操作符+(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;
}

我假设它是double的正则向量(或者更像数组,因为你还没有改变大小),操作符+是两个向量的成员相加

样本中有很多begginer错误,所以让我们先让您了解最新情况:

  • 在没有充分理由的情况下,不要使用除
    int
    double
    char
    size\u t
    以外的其他基元类型(就像使用short一样)
  • 不要在没有充分理由的情况下混用带符号的
    和无符号的
    dim
    d
    ),也不要混用类型(如
    i
    dim
  • 不要通过常量引用传递基元类型(就像您使用
    const int&d
  • 最好对简单的事情使用构造函数,而不是在构造函数体中初始化
  • unsigned
    不能小于
    0
    ,因此
    if(dim<0)
    是冗余的
  • 您可以将
    1
    或甚至
    0
    传递给
    new[]
    ,这样您的
    if
    条件基本上是多余的
  • 你必须
    删除[]
    你借用的内存。析构函数将是一个很好的地方
  • 顺便说一句,你申报了吗