Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.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++;相同的代码从不在Visual Studio中编译/运行,有时在Qt Creator中编译/运行 当我注意到下面的问题时,我正在做一些C++练习。 给定的代码不会在Visual Studio 2013或Qt Creator 5.4.1中运行/编译_C++_Qt_Visual Studio 2013_Qt Creator - Fatal编程技术网

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

c++;相同的代码从不在Visual Studio中编译/运行,有时在Qt Creator中编译/运行 当我注意到下面的问题时,我正在做一些C++练习。 给定的代码不会在Visual Studio 2013或Qt Creator 5.4.1中运行/编译,c++,qt,visual-studio-2013,qt-creator,C++,Qt,Visual Studio 2013,Qt Creator,给出错误: invalid types 'double[int]' for array subscript test[0][0] = 2; ^ 但是,当您第一次将头文件中的第16行(和第17行)更改为 double&运算符[]到double operator[]并在源文件中进行相同的更改->然后编译此文件(同时出现多个错误)->最后将其更改回原始double&operator[]。然后在QtCreator 5.4.1中,它将编译并运行,同时给出预期的结果 编辑:这并不总是有效

给出错误:

invalid types 'double[int]' for array subscript
test[0][0] = 2;
         ^
但是,当您第一次将头文件中的第16行(和第17行)更改为
double&运算符[]
double operator[]
并在源文件中进行相同的更改->然后编译此文件(同时出现多个错误)->最后将其更改回原始
double&operator[]。然后在QtCreator 5.4.1中,它将编译并运行,同时给出预期的结果

编辑:这并不总是有效,但是将其更改为
double*operator[]
而不是
double operator[]
将始终重现问题

为什么会这样

矩阵h

#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>

using namespace std;

class Matrix
{
private:
    double** m_elements;
    int m_rows;
    int m_columns;
public:
    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
#ifndef矩阵
#定义矩阵
#包括
使用名称空间std;
类矩阵
{
私人:
双**m_元素;
int m_行;
int m_列;
公众:
矩阵(int行=1,int列=1);
双精度&运算符[](整数索引);
常量double&运算符[](int索引)常量;
friend ostream&运营商
将返回对列中第一个元素的引用,而不是对列的引用。因此调用
test[0][0]=2;
尝试将
[]
运算符应用于double,而不是double数组

快速解决方案:

double * & Matrix::operator[](size_t index)
{
    return m_elements[index];
}
这将返回对指针的引用(请继续阅读以了解我为什么要处理该引用),您可以在返回的指针上使用[]来访问数据元素

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

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

std::vector<std::vector<double> > m_elements(m_rows, std::vector<double>(m_columns, 0.0));
或者如果必须使用数组

double m_elements = new double[m_rows* m_columns];
然后像这样访问它:

std::vector<double> m_elements(m_rows * m_columns, 0.0);
double &Matrix::at(size_t row, size_t column) 
{
    return m_elements[row * m_rows + column]; 
}
为什么?有很多很好的理由。对我来说,创建、维护和清理一个对象比m_rows+1更容易是一个很好的理由。另一个很好的理由是位置。整个矩阵保证在一个相邻的块中,而不是在这里、那里和马里亚纳海沟底部的RAM中缓存命中数的ds(从而提高了性能)

如果您喜欢数组的外观,那么操作符()重载非常接近

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;
如果您必须有[][] []运算符的建议形式返回对索引数据的引用,在本例中是指向行数组的向量或指针

std::vector<double> & Matrix::operator[](size_t index)
{
    return m_elements[index];
}
数组和向量内部是相同的

<> >警告:这允许用户返回向量或指针引用遇到各种麻烦。考虑<代码>矩阵[0 ] .Culter();<代码> >或代码>矩阵[0 ] = NULL;
double * Matrix::operator[](size_t index)
将通过返回指针的副本来防止大多数滥用。不幸的是,这无法保护向量,因为向量的副本将是一个与源内容副本完全不同的向量。更新它并期望持久性将是徒劳的。必须在包装clas中对用户隐藏向量s、 这很快就变成了太多的工作

此外,返回副本或包装还将阻止引用的合法使用,并违反最小意外法则:矩阵[]运算符与其他[]运算符的工作方式不同,如果不知情的编码人员将其用作常规[]运算符,则可能导致意外行为

我的意见是返回未受保护的引用,如果使用Matrix类的人想开枪打自己的脑袋……那么,你只能做这么多。如果你必须保护用户,请使用上面描述的
at
方法或
operator()
方法

Const[]运算符与向量类似

std::vector<double> const & Matrix::operator[](size_t index) const
我建议的实施:

矩阵h

#ifndef MATRIX_H
#define MATRIX_H

#include <iostream>
#include <vector>

// 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
{
private:
    std::vector<double> m_elements;
    size_t m_rows;
    size_t m_columns;
public:
    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
#ifndef矩阵
#定义矩阵
#包括
#包括
//请注意,使用名称空间std;已不存在。永远不应将其放在标头中
//人们还应该认真考虑将其放入实现文件中
类矩阵
{
私人:
std::向量m_元素;
行的大小;
列的大小;
公众:
矩阵(int行=1,int列=1);
double&运算符()(行大小、列大小);
双运算符()(行大小、列大小)常量;
friend std::ostream和操作员
将返回对列中第一个元素的引用,而不是对列的引用。因此调用
test[0][0]=2;
尝试将
[]
运算符应用于double,而不是double数组

快速解决方案:

double * & Matrix::operator[](size_t index)
{
    return m_elements[index];
}
这将返回对指针的引用(请继续阅读以了解我为什么要处理该引用),您可以在返回的指针上使用[]来访问数据元素

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

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

std::vector<std::vector<double> > m_elements(m_rows, std::vector<double>(m_columns, 0.0));
或者如果必须使用数组

double m_elements = new double[m_rows* m_columns];
然后像这样访问它:

std::vector<double> m_elements(m_rows * m_columns, 0.0);
double &Matrix::at(size_t row, size_t column) 
{
    return m_elements[row * m_rows + column]; 
}
为什么?有很多很好的理由。对我来说,创建、维护和清理一个对象比m_rows+1更容易是一个很好的理由。另一个很好的理由是位置。整个矩阵保证在一个相邻的块中,而不是在这里、那里和马里亚纳海沟底部的RAM中缓存命中数的ds(从而提高了性能)

如果您喜欢数组的外观,那么操作符()重载非常接近

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;
如果您必须有[][] []运算符的建议形式返回对索引数据的引用,在本例中是指向行数组的向量或指针

std::vector<double> & Matrix::operator[](size_t index)
{
    return m_elements[index];
}
数组和向量内部是相同的

<> >警告:这允许用户返回向量或指针引用遇到各种麻烦。考虑<代码>矩阵[0 ] .Culter();<代码> >或代码>矩阵[0 ] = NULL;
double * Matrix::operator[](size_t index)
将通过返回指针的副本来防止大多数滥用。不幸的是,这无法保护向量,因为向量的副本将