c ++构造函数与new

Mar*_*ett 4 c++ constructor new-operator

我只是在一个简单的类中包含指向一些新内存的指针,这是一个非常愚蠢的错误.

class Matrix
{
  public:
    Matrix(int w,int h) : width(w),height(h)
    {           
        data = new unsigned char[width*height];
    }

    ~Matrix() { delete data;    }

    Matrix& Matrix::operator=(const Matrix&p)
    {  
            width = p.width;
            height = p.height;
            data= p.data;
            return *this;
    }
    int width,height;
    unsigned char *data;
}

.........
// main code
std::vector<Matrix> some_data;

for (int i=0;i<N;i++) {
   some_data.push_back(Matrix(100,100)); // all Matrix.data pointers are the same
}
Run Code Online (Sandbox Code Playgroud)

当我用向量的实例填充向量时,内部数据指针最终都指向同一个内存?

Joh*_*ica 7

你错过了复制构造函数.

2.你的赋值运算符不应该只是复制指针,因为它会留下多个Matrix具有相同data指针的对象,这意味着指针将delete多次d.相反,您应该创建矩阵的深层副本.请参阅有关复制和交换习语的问题,其中@GMan提供了有关如何编写高效,异常安全operator=函数的详尽说明.

你需要delete[]在你的析构函数中使用,而不是delete.


GMa*_*ckG 7

无论何时编写复制构造函数,复制赋值运算符或析构函数,都应该执行所有这三个操作.这些是三巨头,之前的规则是三规则.

现在,您的复制构造函数不会执行深层复制.我还建议你在实施三巨头时使用复制和交换习惯用法.*就目前而言,你operator=的不正确.


也许这是一个学习练习,但你应该总是给一个负责任的课程.现在,你的有两个:管理一个内存资源,并成为一个Matrix.您应该将这些分开,以便您有一个处理资源的类,另一个使用该类来使用该资源.

该实用程序类将需要实现三巨头,但是用户类实际上不需要实现它们中的任何一个,因为由于实用程序类,将隐式生成隐式生成的实用程序类.

当然,这样的类已经存在了std::vector.