【问题标题】:reference-to-cont class member initialized with non-const value用非常量值初始化的对 cont 类成员的引用
【发布时间】:2016-01-12 13:17:06
【问题描述】:

我有一个类应该作为其输入数据,或者使用对外部数据的引用(不复制),或者根据其他输入创建数据本身。我更喜欢使用引用(以避免取消引用,因为数据是矩阵)并最终得到以下结构(简化):

#include <iostream>
#include <vector>
using namespace std;
using VectI = vector<int>;

class A {
    VectI x0;
    VectI const & x = x0;
public:
    A(VectI const & extX) : x(extX) {}     // referencing existing external data
    A(int i) { x0.push_back(i); x0.push_back(i*i); }   // create from other data
    void show_x()
        { cout << "x ="; for (auto&& i : x) cout << " " << i; cout << endl; }
};

int main() {
    VectI myX = {1, 2, 3};
    A a(myX); a.show_x(); // a references myX
    A b(2); b.show_x();   // b creates its own data based on i=2
    return 0;
}

示例有效:

x = 1 2 3
x = 2 4

但是这种方法有什么潜在的问题吗? 特别是,我正在更改 const 向量 x 'legal' C++ 引用的 x0,还是其他编译器可能会抱怨?

另外,我可以确定第一个构造函数避免复制数据吗?

【问题讨论】:

  • 代码中没有 const 向量。 x 是一个参考。
  • 这对Code Review 来说可能是个好问题,只要:(A) 代码有效和(B ) 这绝不是假设性的或不完整的。发帖前请阅读on-topic guide,如果你选择去Code Review。如果您有任何问题或疑虑,请通过CR Help Desk 加入我们。
  • 该向量仅在通过引用访问时才被视为 const - 向量本身不是 const - 因此没有问题,但请注意以下内容将编译但具有未定义的行为:@987654330 @.
  • @πάντα ῥεῖ 感谢您的建议。我实际上并不知道 Code Review .. 但从他们的主题指南来看,看起来他们不喜欢简化/最小的示例。无论如何,我从芭丝谢芭那里得到了一个很好的回答。

标签: c++ c++11 const-reference


【解决方案1】:

这在 C++11 标准中很好,但您的代码非常脆弱。

特别是编译器生成的复制和移动构造函数以及赋值运算符将无法正常工作,因此您必须自己构建。

您可能还会遇到悬空引用:请记住,由于 const 引用而导致的对象生命周期延长是不可传递的。将A(VectI const &amp; extX) 与匿名临时对象一起使用的行为未定义。

使用指向 VectI 的指针 - 甚至可能是指向 VectIstd::unique_ptr 以及所有权概念可能是一种更安全的方法。

【讨论】:

  • 感谢您的信息。正如我在上面所写的,我想使用引用,因为它使访问矩阵元素“更好”(与从指向矩阵的指针访问它们相比)。我真的不需要复制或移动构造函数,或者我的应用程序中的赋值,但感谢您的警告。
  • 你可以重载 () 来达到这个目的。
  • 真的吗?假设我使用shared_ptr&lt;VectI&gt; x。为了能够写x(i),我会超载什么?我可以重载指向某物的指针运算符吗?它仍然适用于已经使用() 进行元素访问的 boost/ublas 矩阵吗?
  • 是的。我不反对 A 重载 ()。另外,我建议不要破坏构造函数和赋值运算符之类的东西。您可以(您的继任者)稍后介绍他们。
  • 我很抱歉,但是在 A 的所有方法中,A 的重载 () 如何帮助我不得不写 (*x)[i] 而不是 x[i]? (正如我所说,发布的代码非常简化,我的实际类中有几个这样的数据对象(矩阵)和更多方法,其中许多与输入矩阵一起使用。)
猜你喜欢
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多