Проблема с назначением хода в C ++.Незаконное указание: 4 - PullRequest
0 голосов
/ 17 октября 2018

Я пишу простой класс Matrix, и я определил, среди прочего, оператор + перегрузка и назначение перемещения.Похоже, что-то происходит, когда они взаимодействуют друг с другом, но я не могу найти, где я не прав.Вот мой код (я удалил все лишнее и просто оставил то, что нужно, чтобы показать ошибку).Проблемная строка находится в конце, в основном:

#include <iostream>
#define DEF -1

using namespace std;
//----- Matrix -----//
class Matrix{
private:
    float **matrixpp;
    int dim_r;
    int dim_c;

public:
    Matrix(int d_r = DEF, int d_c = 0);   
    Matrix(const Matrix&);
    Matrix(Matrix&&);
    Matrix& operator=(Matrix&&);
    ~Matrix();

    Matrix operator+(const Matrix&);

    void print();
    void fill();

};

//----- Matrix -----//
Matrix::Matrix(int d_r, int d_c){

    if(d_r == DEF){
        do{
            cout << "number of rows: ";
            cin >> dim_r;
            if(dim_r <= 0){
                cout << "ERROR" << endl;
            }
        }
        while(dim_r <= 0);

        do{
            cout << "Number of columns: ";
            cin >> dim_c;
            if(dim_c <= 0){
                cout << "ERROR" << endl;
            }
        }
        while(dim_c <= 0);


    }
    else{
        dim_r = d_r;
        dim_c = d_c;
    }

    matrixpp = new float*[dim_r];

    for(int i = 0; i < dim_r; i++){
        matrixpp[i] = new float[dim_c];
    }

    for(int r = 0; r < dim_r; r++){
        for(int c = 0; c < dim_c; c++){
            matrixpp[r][c] = 0;
        }
    }
}

Matrix::Matrix(const Matrix& tocopy)
:matrixpp(tocopy.matrixpp), dim_r(tocopy.dim_r), dim_c(tocopy.dim_c)
{

    matrixpp = new float*[dim_r];

    for(int i = 0; i < dim_r; i++){
        matrixpp[i] = new float[dim_c];
    }

    for(int r = 0; r < dim_r; r++){
        for(int c = 0; c < dim_c; c++){
            matrixpp[r][c] = tocopy.matrixpp[r][c];
        }
    }
}

Matrix::Matrix(Matrix&& tomove)
:matrixpp(tomove.matrixpp), dim_r(tomove.dim_r), dim_c(tomove.dim_c)
{
    tomove.matrixpp = nullptr;

}

Matrix& Matrix::operator=(Matrix&& tomove){

    cout << "--- MA ---" << endl;
    matrixpp = tomove.matrixpp;
    dim_r = tomove.dim_r;
    dim_c = tomove.dim_c;

    tomove.matrixpp = nullptr;
}

Matrix::~Matrix(){

    if(matrixpp != nullptr){
        for(int i = 0; i < dim_r; i++){
            delete[] matrixpp[i];
        }
        delete[] matrixpp;
    }
}

Matrix Matrix::operator+(const Matrix& m){

    if(this->dim_r == m.dim_r && this->dim_c == m.dim_c){
        Matrix new_m(m.dim_r, m.dim_c);

        for(int r = 0; r < new_m.dim_r; r++){
            for(int c = 0; c < new_m.dim_c; c++){
                new_m.matrixpp[r][c] = this->matrixpp[r][c] + m.matrixpp[r][c];
            }
        }

        return new_m;
    }
    else{
        cout << "ERROR" << endl;
    }
}

void Matrix::print(){
    int temp;

    for(int r = 0; r < dim_r; r++){
        for(int c = 0; c < dim_c; c++){
            cout << matrixpp[r][c] << " ";

        }
        cout << endl;
    }
    cout << endl;
}

void Matrix::fill(){
    float temp;

    for(int r = 0; r < dim_r; r++){
        for(int c = 0; c < dim_c; c++){
            cout << "new value: " << endl;
            this->print();
            cin >> temp;
            matrixpp[r][c] = temp;
            system("clear");
        }
    }
}

//-------- Main -------//
int main(){

    Matrix m0;
    m0.fill();
    Matrix m1(0);

    m1 = m0+m0; // problematic line

    //m1.print();

}

Она выдает ошибку при вызове присваивания перемещения для перемещения результата m0 + m0 в m1.

ЕслиЯ компилирую свой код с помощью g ++ на Mac, но с ошибкой просто «Недопустимая инструкция: 4», ни больше, ни меньше.Если я делаю это в Linux, выдается ошибка:

В функции-члене 'Matrix Matrix :: operator + (const Matrix &)': p.cpp: 90: 16: error: использование удаленногофункция 'constexpr Matrix :: Matrix (const Matrix &)' return new_m;^ ~~~~ p.cpp: 9: 7: примечание: 'constexpr Matrix :: Matrix (const Matrix &)' неявно объявлен как удаленный, потому что 'Matrix' объявляет конструктор перемещения или оператор оператора присваивания класса Matrix {^ ~~~~~

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Проблема заключается в том, что при использовании стандарта, предшествующего C ++ 17, нет гарантии исключения копирования, поэтому возвращение значения из функции следует семантике инициализации копирования, которая требует определения конструктора перемещения или копирования.Определение собственного оператора назначения перемещения отключает автоматическую генерацию конструктора ( Правила генерации CTOR для копирования классов ).Фактически конструктор, предоставленный компилятором, определен, но удален.Чтобы решить эту проблему, вы должны определить конструктор перемещения или копирования или оба из них в соответствии с правилом пяти ( Правило трех / пяти / ноль ).

Также я подозреваю, что исходная проблема (недопустимая инструкция) вызвана множеством неопределенных поведений в вашем коде (например, нет оператора возврата в вашем операторе присваивания и нет возврата в операторе + ветвь else).

0 голосов
/ 17 октября 2018

главная проблема в том, что ваш оператор = не имеет никакого возврата.

перегрузите оператор + следующим образом:

Matrix operator+(const Matrix &A ,const Matrix &m)
{
if(A->dim_r == m.dim_r && A->dim_c == m.dim_c){
    Matrix new_m(m.dim_r, m.dim_c);

    for(int r = 0; r < new_m.dim_r; r++){
        for(int c = 0; c < new_m.dim_c; c++){
            new_m.matrixpp[r][c] = A->matrixpp[r][c] + m.matrixpp[r][c];
        }
    }

    return new_m;
}
else{
    cout << "ERROR" << endl;
}

и сделайте его другом своего класса.и в конце оператора = добавить оператор возврата следующим образом:

Matrix& Matrix::operator=(Matrix&& tomove){
        if(this != &tomove) { 
        cout << "--- MA ---" << endl;
        matrixpp = tomove.matrixpp;
        dim_r = tomove.dim_r;
        dim_c = tomove.dim_c;

        tomove.matrixpp = nullptr;
    }
    return *this;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...