【问题标题】:Problems returning a const reference (no a reference to a const) [closed]返回 const 引用的问题(没有对 const 的引用)[关闭]
【发布时间】:2020-10-16 12:00:23
【问题描述】:

我想返回一个 const 引用,所以我不能更改对象本身,但我可以调用它们的非 const 方法。但我不知道该怎么做。

使用指针很容易,我可以在 const 指针 (const myclass*) 或指向 const 值的指针 (myclass const*) 之间进行选择。但是对于引用,它的工作方式似乎不一样,我所得到的只是对 const 对象的引用,所以我不能调用非 const 方法。

我确定我做错了什么。

class A {
   int a;
public:
   auto get() const { return a; }
   auto set(int i) -> void { a = i; }
};

class B {
  A a_;
public:
  auto get() const -> const A& { return a_; }
};

我能做到:

B b;
cout << b.get().get();

但不是:

B b;
b.get().set(100); // compiler error

我不想

class B {
  A a_;
public:
  auto get() -> A& { return a_; }
};

B b;
A a;
b.get() = a; // I don't want this!

【问题讨论】:

  • "我想返回一个 const 引用,因此我不能更改对象本身,但我可以调用它们的非 const 方法"。这些是相互矛盾的要求。
  • What is the xy problem?。为什么你认为你需要这个?您要解决的实际问题是什么?
  • 您无法更改引用所指的对象,因此以T* const 的方式“const 引用非 const”(T&amp; const)将毫无意义。
  • 如果您希望能够通过其成员修改对象,但不分配给它,您也不能使用指针来执行此操作(除非您将其设为完全不可分配)。跨度>
  • “我想返回一个 const 引用,所以我不能更改对象本身” - 你这样说,但是你的示例尝试通过调用 set(100) 来更改对象。 ..?

标签: c++ reference constants


【解决方案1】:

如果没有从 A 中完全删除分配,您就不能以这种方式拥有“部分可变性”。
(尽管您声称使用指针很容易,但情况完全相同 - 您需要禁止 b.get()-&gt;set(100) 或允许 *b.get() = a。)

您可以做的一件事是通过代理对象添加一个间接级别:

class A_Setter
{
public:
    A_Setter(A* a): the_a(a) {}
    A_Setter& operator=(const A_Setter&) = delete;

    void set(int x) { the_a->set(x); }
private:
    A* the_a;
};

class B {
    A a_;
public:
    A_setter get() { return A_setter(&a_); }
};

现在b.get().set(100); 将编译,而不是b.get() = a;

【讨论】:

    【解决方案2】:

    返回 const 引用的问题(没有对 const 的引用)

    技术上没有 const 引用这样的东西。引用没有顶级 cv 限定符。 const 引用通俗地表示对 const 的引用。

    我想返回一个 ... 引用,所以我不能更改对象本身

    对象不能通过对 const 的引用来修改,所以这样可以。

    ...但我 [想] 调用他们的非常量方法。

    非常量成员函数只能通过引用非常量来调用。没有任何参考类别可以同时满足您的两个需求。它们是矛盾的。

    使用指针很容易,我可以在 const 指针 (const myclass*) 或指向 const 值的指针 (myclass const*) 之间进行选择。

    那些也没有达到你想要的。可以通过 const 指针(指向非 const)修改指向对象,不能通过指向 const 的(非 const)指针调用指向对象的 const 成员函数。两者都达不到你的要求。


    附:返回一个 const(或 volatile)限定指针 - 或任何其他内置类型 - 是没有意义的,因为对此类函数的函数调用是纯右值表达式,并且非类类型的纯右值没有 cv 限定符,因此此类返回类型的限定符总是会被忽略。不要将这与返回有意义的 cv 限定类型的指针相混淆。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-24
      相关资源
      最近更新 更多