sách gpt4 ai đã đi

Mã tương tự không bao giờ biên dịch/chạy trong Visual Studio, đôi khi biên dịch/chạy trong Qt Creator

In lại 作者:行者123 更新时间:2023-11-27 22:56:47 29 4
mua khóa gpt4 Nike

当我注意到以下问题时,我正在做一些 C++ 练习。给定的代码将不会在 Visual Studio 2013 或 Qt Creator 5.4.1 中运行/编译

报错:

invalid types 'double[int]' for array subscript
test[0][0] = 2;
^

然而,当您第一次更改头文件中的第 16(和 17)行时double &operator[]; đến double operator[] 并在源文件中进行相同的更改 -> 然后编译它(同时出现多个错误) -> 最后更改它回到原来的 double &operator[];。然后在 Qt Creator 5.4.1 中它将编译并运行,同时给出预期的结果。

编辑:这并不总是有效,但是将其更改为 double *operator[] Còn hơn là double operator[] 总是会重现问题。

为什么会这样?

矩阵.h

#ifndef MATRIX_H
#define MATRIX_H

#include

sử dụng không gian tên std;

class Matrix
{
riêng tư:
double** m_elements;
int m_rows;
int m_columns;
công cộng:
Matrix(int rows = 1, int columns = 1);
double &operator[](int index);
const double &operator[](int index) const;
friend ostream &operator<<(ostream &ostr, Matrix matrix);
};

#endif // MATRIX_H

矩阵.cpp

#include "matrix.h"

Matrix::Matrix(int rows, int columns)
{
m_rows = rows;
m_columns = columns;
m_elements = new double*[rows];
for(int i=0; i
{
m_elements[i] = new double[columns];
for(int j=0; j
m_elements[i][j] = 0;
}
}

double &Matrix::operator[](int index)
{
return *(m_elements[index]);
}

const double &Matrix::operator[](int index) const
{
return *(m_elements[index]);
}

ostream &operator<<(ostream &ostr, Matrix matrix)
{
for(int i=0; i
{
for(int j=0; j
{
ostr << matrix.m_elements[i][j] << " ";
}
ostr << "\n";
}
return ostr;
}

主要

#include 
#include "matrix.h"

sử dụng không gian tên std;

int chính()
{
Matrix test(4,4);
test[0][0] = 2;
cout << test;

trả về 0;
}

1 Câu trả lời

double &Matrix::operator[](int index)
{
return *(m_elements[index]);
}

将返回对列中第一个元素的引用,而不是该列。因此调用 test[0][0] = 2; Cố gắng [] 运算符应用于 double ,而不是 double 数组。

快速解决方案:

double * & Matrix::operator[](size_t index)
{
return m_elements[index];
}

这会返回对指针的引用(请继续阅读以了解我为何为该引用烦恼),您可以在返回的指针上使用 [] 来获取数据元素。

但是...

有更好的方法可以做到这一点。

如果可能,使用 std::vector 而不是动态数组。

std::vector<> > m_elements(m_rows, std::vector(m_columns, 0.0));

这将解决很多潜在的问题,并一次性将矩阵初始化为 0。它不会解决 [][] 索引虽然。这仍然需要一些工作。

进行索引的最简单和最安全的方法是根本不使用 [] 运算符。而是定义一个新方法。通过这种方式,您可以完全控制公开的内容,并且可以在超出范围之前完全测试输入的有效性。

double &Matrix::at(size_t row, size_t column) 
{
// optional overrun defence if desired
if (row < m_rows || column < m_columns)
{
return m_elements[row][column];
}
throw std::out_of_range("Matrix indices out of range");
}
double Matrix::at(size_t row, size_t column) const
{
// put overrun defence here if desired
return m_elements[row][column];
}
matrix.at(2,3) = 2;
constmatrix.at(2,3) = 2; // bad lvalue compiler error

请注意使用 size_t thay thế số nguyên。 size_t 是无符号的,因此无需对负数进行有效性检查。不能有负数数组索引,那为什么要允许这种可能性呢?

同样值得注意的是,这种方法可以很容易地将矩阵的存储定义为一维数组,如下所示:

std::vector m_elements(m_rows * m_columns, 0.0);

或者如果你必须使用数组

double m_elements = new double[m_rows* m_columns];

并像这样访问它:

double &Matrix::at(size_t row, size_t column) 
{
return m_elements[row * m_rows + column];
}

为什么?有很多很好的理由。比 m_rows +1 更容易创建、维护和清理一个对象,这对我来说是一个足够好的理由。另一个极好的原因是地方。整个矩阵保证在一个连续的 block 中,而不是这里一个数组,那里另一个数组,还有一个在 RAM 中,相当于马里亚纳海沟底部。缓存命中率(以及性能)大幅提升。

如果您更喜欢数组的外观和感觉,operator() 重载非常接近。

double &Matrix::operator()(size_t row, size_t column) 
{
return m_elements[row][column];
}
double Matrix::operator()(size_t row, size_t column) const
{
return m_elements[row][column];
}
matrix(2,3) = 2;

如果你必须有[][]

[] 运算符的建议形式返回对索引数据的引用,在本例中为 vector 或指向行数组的指针。

std::vector & Matrix::operator[](size_t index)
{
return m_elements[index];
}

hoặc

double * & Matrix::operator[](size_t index)

数组和 vector 的内部结构是相同的。

警告:这允许用户使用返回的 vector 或指针引用来解决各种问题。以 matrix[0].clear(); hoặc matrix[0] = NULL; 为例。

double * Matrix::operator[](size_t index)

将通过返回指针的拷贝来防止大多数滥用。不幸的是,这不能保护 vector ,因为 vector 的拷贝将是与源内容拷贝完全不同的 vector 。更新它并期望持久性是徒劳的。 vector 必须在包装类中对用户隐藏,而这很快就会成为太多的工作。

此外,返回拷贝或包装器也会阻止引用的合法使用并违反最小惊奇法则:Matrix [] 运算符与其他 [] 运算符的工作方式不同,如果出现以下情况,可能会导致意外行为毫无戒心的编码人员将其用作常规 [] 运算符。

我的意见是返回未 protected 引用,如果使用 Matrix 类的人想朝自己的脑袋开枪......好吧,你只能做这么多。如果您必须保护用户,请使用上述 at 方法或 operator() phương pháp.

Const[] 运算符对于 vector 是类似的

std::vector const & Matrix::operator[](size_t index) const

但数组不同,因为指针和指向的值都应该是 const

double const * const & Matrix::operator[](size_t index) const

我建议的实现方式:

矩阵.h

#ifndef MATRIX_H
#define MATRIX_H

#include
#include

// note that the using namespace std; is gone. One should never put it in the header
// and one should also think hard about putting it in the implementation file
class Matrix
{
riêng tư:
std::vector m_elements;
size_t m_rows;
size_t m_columns;
công cộng:
Matrix(int rows = 1, int columns = 1);

double &operator()(size_t row, size_t column);

double operator()(size_t row, size_t column) const;

friend std::ostream &operator<<(std::ostream &ostr, const Matrix & matrix);
};

#endif // MATRIX_H

矩阵.cpp

#include 
#include "Matrix.h"

Matrix::Matrix(int rows, int columns):
m_elements(rows * columns, 0.0),
m_rows(rows),
m_columns(columns)
{
}

std::ostream &operator<<(std::ostream &ostr, const Matrix &matrix)
{
for(size_t i=0; i
{
for(size_t j=0; j
{
ostr << matrix(i,j) << " ";
}
ostr << std::endl;
}
return ostr;
}

double &Matrix::operator()(size_t row, size_t column)
{
if (row < m_rows && column < m_columns)
{
return m_elements[row * m_rows + column];
}
throw std::out_of_range("Matrix indices out of range");
}

double Matrix::operator()(size_t row, size_t column) const
{
if (row < m_rows && column < m_columns)
{
return m_elements[row * m_rows + column];
}
throw std::out_of_range("Matrix indices out of range");
}

关于c++ 相同的代码从不在 Visual Studio 中编译/运行,有时在 Qt Creator 中编译/运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32036345/

29 4 0
Bài viết được đề xuất: html - Flexbox 列垂直间距不起作用
Bài viết được đề xuất: c++ - 指向参数较少的函数
Bài viết được đề xuất: c++ - 如何将一个字符串转换为一长串或另一串 ascii 值?
Bài viết được đề xuất: C++ 创建和初始化数组的最佳方式
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com