C++ 模板复制构造函数,编译器说“传递 const 作为此参数丢弃限定符”

2024-04-07

我正在尝试创建动态矩阵的模板类。以我目前对 C++ 的了解,我设法解决了一些问题,但我陷入了复制构造函数和重载运算符 =; 的困境。换句话说,我无法创建我的对象的副本。 在我看来,这应该可行,但我的朋友编译器告诉我,我有 1 个错误: 错误:将“const Matrix”作为“int Matrix::getElement(int, int) [with T = int]”的“this”参数传递会在这一行丢弃限定符[-fpermissive]:

m[i][j] = original.getElement(i, j);

当我想创建一个对象时:

Matrix<int> m = Matrix<int>(3, 3);

我的模板类在这里:

template<class T>class Matrix
{
 public:

  Matrix<T>(int lines, int columns)
  {
    this->lines = lines;
    this->columns = columns;
    T* aux = new T[this->lines * this->columns];
    m = new T*[lines];
    for (int i = 0; i < this->lines; i++)
    {
      m[i] = aux + (i * this->columns);
    }
    for (int i = 0; i < this->lines; i++)
    {
      for (int j = 0; j < this->columns; j++)
      {
        m[i][j] = 0;
      }
    }
  }

  Matrix<T>(const Matrix<T>& original)
  {
    columns = original.getColumns();
    lines = original.getLines();
    T* aux = new T[this->lines * this->columns];
    m = new T*[lines];
    for (int i = 0; i < lines; i++)
    {
      m[i] = aux + (i * this->columns);
    }
    for (int i = 0; i < lines; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        m[i][j] = original.getElement(i, j);
      }
    }
  }

  virtual ~Matrix<T>()
  {
    /*for (int i = lines - 1; i > 0; i--)
    {
      delete m[i];
    }*/
    delete [] m;
  }

  T** getPointer()
  {
    return m;
  }

  int getLines () const
  {
    return lines;
  }

  int getColumns () const
  {
    return columns;
  }

  int getElement(int line, int column)
  {
    return m[line][column];
  }

  int setElement(int line, int column, T value)
  {
    m[line][column] = value;
  }

  Matrix<T>* getTranspose()
  {
    Matrix<T>* aux = new Matrix<T>(lines, columns);
    for (int i = 0; i < lines; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        aux->setElement(i,j, m[j][i]);
      }
    }
    return aux;
  }

  Matrix<T> operator=(const Matrix<T> original)
  {
    columns = original.getColumns();
    lines = original.getLines();
    T* aux = new T[this->lines * this->columns];
    m = new T*[lines];
    for (int i = 0; i < lines; i++)
    {
      m[i] = aux + (i * this->columns);
    }
    for (int i = 0; i < lines; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        m[i][j] = original.getElement(i, j);
      }
    }
  }

  friend std::ostream& operator<<(std::ostream& out, Matrix<T>& matrix)
  {
    out<<"Matrix:"<<std::endl;
    for (int i = 0; i < matrix.getLines(); i++)
    {
      for (int j = 0; j < matrix.getColumns(); j++)
      {
        out<<matrix.getElement(i, j)<<" ";
      }
      out<<std::endl;
    }
    return out;
  }

  friend std::istream& operator>>(std::istream& in, Matrix<T>& matrix)
  {
    std::cout << "Reading Matrix:\n";
    for (int i = 0; i < matrix.getLines(); i++)
    {
      for (int j = 0; j < matrix.getColumns(); j++)
      {
        std::cout << "Matrix[" << i << "][" << j << "]:";
        in >> matrix.m[i][j];
      }
      std::cout << std::endl;
    }
    return in;
  }

 private:
  T** m;
  int lines;
  int columns;
};

正如我可以从该错误中找出的那样,我正在创建 2 个引用同一内存块的对象,但我想创建 2 个引用具有相同内容的不同内存块的 2 个对象。


在你的复制构造函数中

Matrix<T>(const Matrix<T>& original)

original被声明为 const 引用,这非常好。但是,这意味着您不得调用Matrix<T>其上未声明为const功能。

The getElement函数未声明为const所以你不能在复制构造函数中使用它。通过将其声明为 const 函数来解决此问题:

int getElement(int line, int column) const  // <--- Note the 'const'
{
  return m[line][column];
}

这意味着:

  1. 这个函数可以被调用Matrixconst 对象(例如original在你的复制构造函数中)

  2. 您无法在里面执行任何操作getElement修改当前实例Matrix(即修改*this).

前者是我们想要的,后者不是问题,因为getElement只是一个 getter 方法,所以不需要修改任何东西。

请注意,正因为如此,最好always将成员函数标记为const当他们不应该修改任何东西时。这意味着您可以将它们应用于常量对象,并且意味着编译器会告诉您是否错误地将代码放入实际修改某些内容的函数中。

最后评论:正如托雷·奥尔森 (Tore Olsen) 所指出的,getElement函数应该返回一个对象或类型的引用T而不是int.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 模板复制构造函数,编译器说“传递 const 作为此参数丢弃限定符” 的相关文章

随机推荐

  • 如何更改 Angular-Chart.js 的颜色

    我使用 Angular Chart js AngularJSChart js http www chartjs org 版本 来创建条形图 图表正在使用除颜色之外的选项 即使我设置了它们 它也会显示在文档中 http jtblin gith
  • Python if 语句无法正常工作

    我是一个非常新的 Python 用户 2 7 一直在努力学习 Python The Hard Way 课程 一直到第 37 章 并决定阅读一些其他学习材料 再次复习基础知识并在那里做练习 我一直在读这个 http anh cs luc ed
  • Asp.Net MVC 区域,我该如何使用它们?

    我有两个关于 Asp Net MVC 领域的问题 从我在各种播客中听到的内容来看 我对这些领域的了解只有肤浅的了解 但我认为我相当了解它们的用途 现在我的问题是我是否也可以使用它们来使我能够逐渐从使用 VB 的 Asp Net Webfor
  • 在 NumPy 数组中查找等于 0 的元素索引

    NumPy 具有高效的函数 方法nonzero http docs scipy org doc numpy reference generated numpy nonzero html识别非零元素的索引ndarray目的 获取元素索引的最有
  • 如何使用 WorkManager 安排通知?

    我想在每次用户在数据库中添加特定时间的注释时安排通知 虽然使用 AlarmManager BroadcastReceiver 等有多种方法可以做到这一点 但如何使用 WorkManager 来完成呢 WorkManager不适合需要在特定时
  • Bootstrap 3.0 和 Google 地图 javascript API V3 样式

    我正在尝试将谷歌地图 javascript API v3 实现到利用 Bootstrap 3 0 轮播 基本主题的 Bootstrap 3 0 网站中 问题是 div div 如果我尝试将其包含在任何其他 div 或 bootstrap 3
  • 如何使用 RTTI 区分 TDateTime 属性和 Double 属性?

    使用Delphi 2010中的RTTI系统 有什么方法可以找出属性是否是TDateTime 目前 每当我回调 asVariant 以及检查属性类型时 它都会将其视为双精度 这是因为它只能看到基本类型吗 TDateTime 双精度 尝试检查N
  • 如何正确使用AddBatch/withBatch将xml标签值批量插入数据库表

    innerXml 是一个带有大量 xml 标签的 xml 文件 我正在尝试获取标签值并将它们转储到数据库表中 我已经尝试过下面的代码 它工作正常 innerXml Row each Row gt sql execute INSERT INT
  • adb 已停止在 android studio 中工作

    我正在尝试在 android studio 中构建我的第一个应用程序并收到错误 adb exe 已停止工作 我正在Windows xp 32位系统上工作 Have tried several solutions available onli
  • 如何更新 JRuby 的 gem 命令?

    我们如何更新 JRuby 使用的 gem 版本 JRuby 使用 gem 1 5 1 我们希望将其升级到 1 8 7 我们希望将 gems 安装在 Ruby gems 中 We run bin jruby gem install rubyg
  • NuGet:远程服务器返回错误(403)禁止

    每当我尝试安装软件包时 我都会收到此错误 remote server returned an Error 403 Forbidden 我可以使用其他命令 例如 get package ListAvailable 并发现已安装的软件包是否有任
  • 在部署之前使用 local :path 检查 gems

    对于某些 Rails 应用程序 我希望在部署时有一个安全防护措施 以检查是否有一些 gem 配置为在本地路径中查找 一些上下文可能有助于理解 当我处于开发模式时 我希望在 本地模式 下有一个 gem 在我的Gemfile它的配置如下 gem
  • Node fs 复制文件夹

    我正在尝试使用 Node 复制文件夹fs模块 我熟悉readFileSync and writeFileSync 方法 但我想知道应该使用什么方法来复制指定的文件夹 您可以使用fs extra https www npmjs com pac
  • 无法读取文本框值

    我在 AjaxFileUpload1 的 pageupload 事件期间将页面上的文本框的值分配给变量 问题是 即使没有错误抛出 我也没有从文本框获取值到我的变量 我的变量是 string scn txtSCN Text string li
  • CodeIgniter 验证变量/输入不是来自表单?

    假设我有用户生成的数据 这些数据不是通过表单发布的 有没有办法可以使用 扩展 CodeIgnitors form validation 类来验证该数据 eg 是的 您可以通过set data
  • 将一个整数平均分为 X 部分

    我正在 PHP 中寻找一种有效的方法来将数字等分 数字始终是整数 没有浮点数 假设我有一个数组 hours 其值从 1 到 24 hours 1 等 和一个包含整数的变量 int 我想要实现的是将 int 的值平均分为 24 个部分 这样我
  • 标签中的 Ember 车把模板

    ember 特别是应用程序模板 是否可以在 head 标签内进行操作 以便动态更改标题标签 元标签 外部 css 样式表和 favicon 等内容 如果是这样 那么一种干净的方法是什么 为了完成这项工作 我所做的是创建车把助手 例如 如果您
  • 保存用户个人资料详细信息 Android 应用程序的最佳方式

    我正在创建一个有多个用户的应用程序 我创建了一个对象 用户 其中包含更多详细信息 姓名 年龄 自定义对象等 因为我有一个自定义对象 所以我知道使用共享首选项会很困难 存储用户数据的最佳方式是什么 我研究过 SQLite 但找不到将自定义对象
  • 有没有办法从应用程序脚本中的 graphql API 获取数据?

    我正在尝试通过应用程序脚本从 graphql API 获取数据 使用 POST 获取 graphql 数据有一个问题 提供从 GraphQL API 获取的查询字符串 https stackoverflow com questions 47
  • C++ 模板复制构造函数,编译器说“传递 const 作为此参数丢弃限定符”

    我正在尝试创建动态矩阵的模板类 以我目前对 C 的了解 我设法解决了一些问题 但我陷入了复制构造函数和重载运算符 的困境 换句话说 我无法创建我的对象的副本 在我看来 这应该可行 但我的朋友编译器告诉我 我有 1 个错误 错误 将 cons