Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;,类的对象在创建新对象时发生更改_C++_C++11 - Fatal编程技术网

C++ c++;,类的对象在创建新对象时发生更改

C++ c++;,类的对象在创建新对象时发生更改,c++,c++11,C++,C++11,我创建了一个类矩阵,除了有一些成员函数外,运算符和构造函数还有两个变量: int m,它是二次矩阵的维数(边长) 双精度a[],它包含矩阵的元素 只要我只创建一个矩阵对象,所有的操作似乎都很好,我的所有成员操作符和函数都能正常工作 我的问题是,一旦我创建了类矩阵的第二个对象B,对象a的变量也会改变 有关守则如下: class Matrix{ private: const int m; double a[]; public: Matr

我创建了一个类矩阵,除了有一些成员函数外,运算符和构造函数还有两个变量:

int m,它是二次矩阵的维数(边长)

双精度a[],它包含矩阵的元素

只要我只创建一个矩阵对象,所有的操作似乎都很好,我的所有成员操作符和函数都能正常工作

我的问题是,一旦我创建了类矩阵的第二个对象B,对象a的变量也会改变

有关守则如下:

class Matrix{
    private:
        const int m;
        double a[];
    public:
        Matrix(int inpm);
        void fillMatrix(const double inpa[]);
};
Matrix::Matrix(int inpm): m(inpm){
    a[impm*inpm];
}
void Matrix::fillmatrix(const double inpa[]){
    for (int i ; i<m*m ; i++){
        a[i]=inpa[i];
    }
}

int min =2;
double ain[min*min] = {1,2,3,4};
double bin[min*min] = {5,6,7,8};

Matrix A(min);
Matrix B(min);

A.fillMatrix(ain);
//A looks precisely as it should here:
//m=2, a={1,2,3,4}
B.fillMatrix(bin);
//Here B looks as it should but A has changed to:
//m=0, a={7,8,3,4}
类矩阵{
私人:
常量int m;
双a[];
公众:
矩阵(int-inpm);
空隙填充矩阵(常数双inpa[]);
};
矩阵::矩阵(int-inpm):m(inpm){
a[impm*inpm];
}
无效矩阵::填充矩阵(常数双inpa[]){

对于(inti;i
a[impm*inpm];
这与您的想法不符。
GCC
即使使用
语句发出警告也没有效果

a
在此保持未初始化状态,当您尝试访问
a[i]

class Matrix{
private:
    const int m;
    double *a;
    ....

然后记得
删除

Matrix::~Matrix()
{
   delete a;
}

c++
数组实际上不允许可变。有。如果您不希望在运行时选择大小为的动态长度数组,则需要分配一些内存:

double *a;
...
a = new double[inpm*inpm];

但是这太糟糕了!现在你必须记住正确地删除所有的东西。你可以把这个内存打包在一个类中来控制这个,因为这是个好主意,C++提供了这个标准。它被调用。你的代码会很好地减少到:

class Matrix{
private:
    const int m;
    std::vector<double> a;
public:
    Matrix(int inpm) : m(inpm), a(m * m) {}
类矩阵{
私人:
常量int m;
std::载体a;
公众:
矩阵(int-inpm):m(inpm),a(m*m){

我注意到您的代码存在一些问题。前几个问题已经被其他人提到,比如您的会员
double a[]这是未初始化的,C++不允许使用可变长度的向量。为了解决这个问题,我将马上讨论两种可能的解决方案。其他人提到的另一个问题是,在你的<代码>矩阵::fMatMatRX()中。
函数for循环
i
中的变量也未初始化,因此
i
可以是任何变量,这将导致未定义的行为

其他人未提及的几个问题如下:

class Matrix{
    private:
        const int m;
        double a[];
    public:
        Matrix(int inpm);
        void fillMatrix(const double inpa[]);
};
Matrix::Matrix(int inpm): m(inpm){
    a[impm*inpm];
}
void Matrix::fillmatrix(const double inpa[]){
    for (int i ; i<m*m ; i++){
        a[i]=inpa[i];
    }
}

int min =2;
double ain[min*min] = {1,2,3,4};
double bin[min*min] = {5,6,7,8};

Matrix A(min);
Matrix B(min);

A.fillMatrix(ain);
//A looks precisely as it should here:
//m=2, a={1,2,3,4}
B.fillMatrix(bin);
//Here B looks as it should but A has changed to:
//m=0, a={7,8,3,4}
在构造函数定义中,您试图使用[impm*inpm]
初始化
m
,我认为这可能是您的输入错误。另一个是您将函数声明为
::fillMatrix()
,但您在类声明之外将其定义为
::fillMatrix()
。我想这可能只是你的打字错误

至于上面关于在
C++
中使用数组的问题,最简单的方法是其他人已经说过的,那就是使用
std::vector


另一种方法是编写一个类似于
std::vector
但具有矩阵机制的类。使用模板时,您的类看起来像这样:如果您在运行时想要一个可变长度的容器,您必须在编译时知道它的大小,在这里使用模板可以帮助您,因为模板必须在编译时推导实例化的时间

template<class T, unsigned N>
class Matrix {
private:
    static const unsigned Stride = N;
    static const unsigned Size = Stride * Stride;
    T data[Size] = {};

public:
    Matrix() {};

    void fillMatrix( const T* dataIn );
    void printMatrix();
};

template<class T, unsigned N>
void Matrix<T, N>::fillMatrix( const T* dataIn ) {
    for( unsigned int i = 0; i < Size; i++ ) {
        this->data[i] = dataIn[i];
    }
}

template<class T, unsigned N>
void Matrix<T, N>::printMatrix() {
    for( unsigned int i = 0; i < Stride; i++ ) {
        for( unsigned int j = 0; j < Stride; j++ ) {
            std::cout << this->data[i*Stride + j] << " ";
        }
        std::cout << '\n';
    }
}

int main() {        
    // 2x2 = 4
    double ain[4] = { 1,2,3,4 };
    double bin[4] = { 5,6,7,8 };

    Matrix<double, 2> A;
    Matrix<double, 2> B;

    A.fillMatrix( ain );
    A.printMatrix();
    std::cout << '\n';

    B.fillMatrix( bin );
    B.printMatrix();
    std::cout << '\n';

    // test A again
    A.printMatrix();
    std::cout << '\n';
    B.printMatrix();
    std::cout << '\n';    

    // Try it with other types
    // 3x3 = 9
    char data[9] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' };
    Matrix<char, 3> C;
    C.fillMatrix( data );
    C.printMatrix();
    std::cout << '\n';

    return 0;
}

使用模板的这种设计,不限于只使用一个<代码>类型> <代码> > <代码>浮点< /代码>等。您甚至可以使用<代码>用户定义的类型< /代码>。这里唯一需要考虑的是< <代码> >运算符< /代码>。将始终创建一个

MxM
矩阵,该矩阵将始终是一个方形矩阵。如果您需要一个非方形矩阵,您只需将第二个无符号常量值添加到模板参数列表中,并将它们相应地重命名为
MxN
。然后只需替换它们在数学中所属的位置。这样看起来会有些问题像这样:

template<class T, unsigned M, unsigned N>
class Matrix {
private:
    static const unsigned Row = M;
    static const unsigned Col = N;
    static const unsigned Size = Row * Col;

    T data[Size] = {};
};
模板
类矩阵{
私人:
静态常量无符号行=M;
静态常量无符号列=N;
静态常量无符号大小=行*列;
T数据[Size]={};
};

现在,如何标记它们可能取决于您是想要
行列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列列。而且它不会像您预期的那样工作。此外,在使用灵活的数组时,还需要遵循某些规则。

但是如果你想创建一个动态数组,你可以使用Maloc动态创建数组。

<代码>双A[]; >甚至不应被接受为有效C++。(int i;我在这里发布时,不要写任何东西。复制粘贴实际上是编译代码。当自己编写代码而不理解代码时,也要提高编译器的警告级别。编译器会告诉你一些关于代码的不好的地方,如果你不理解它,你可以在互联网上找到很多地方来解释它。没有原始版本请使用智能指针或容器。
template<class T, unsigned M, unsigned N>
class Matrix {
private:
    static const unsigned Row = M;
    static const unsigned Col = N;
    static const unsigned Size = Row * Col;

    T data[Size] = {};
};