const数据成员是否可以在类外更改?

问题描述 投票:2回答:2

如果一个类的const引用数据成员碰巧在此类范围之外进行更改,那么这种不确定的行为是吗?

作为示例,让我们考虑以下C ++代码:

#include <iostream>

class A {
  int x;
public:
  A(int x): x(x){}
  void change(int y){
    x = y;
  }
  friend std::ostream & operator << (std::ostream & os, const A & a){
    os << a.x;
    return os;
  }
};

class B {
  const A & a;
public:
  B(const A & a) : a(a) {}
  friend std::ostream & operator << (std::ostream & os, const B & b){
    os << b.a;
    return os;
  }
};

int main(){
  A a(1);
  B b(a);
  std::cout << a << std::endl;
  std::cout << b << std::endl;
  a.change(2);
  std::cout << a << std::endl;
  std::cout << b << std::endl;
}

我的编译器能够正确执行它,并且调试器指示B :: a的x已更改。

谢谢您的帮助!

c++ reference const constants
2个回答
2
投票

这不是未定义的行为。作为const成员的B引用仅表示B的实例不能通过该引用对其进行更改。但是,因为它是一个引用,所以可能会对其进行某些更改-包括B的其他成员,它们对const的相同实例具有自己的非A引用。

比较成员c与您现有的B类的添加,请注意,我们正在B::changeA()内通过非const引用成功地对其进行更改,并且在C::change()中从main()向下进行了更改) :

#include <iostream>

class A {
  int x;
public:
  A(int x): x(x){}
  void change(int y){
    x = y;
  }
  friend std::ostream & operator << (std::ostream & os, const A & a){
    os << a.x;
    return os;
  }
};

class C
{
    A& a;
public:
    C(A& a) : a{a} {}
    void change(int y) { a.change(y); }
};

class B {
  const A & a;
  C& c;
public:
  B(const A & a, C& c) : a(a), c{c} {}
  friend std::ostream & operator << (std::ostream & os, const B & b){
    os << b.a;
    return os;
  }
  void changeA(int y) { c.change(y); }
};

int main(){
  A a(1);
  C c(a);
  B b(a,c);

  std::cout << a << ' ' << b << '\n';

  a.change(2);
  std::cout << a << ' ' << b << '\n';

  b.changeA(3);
  std::cout << a << ' ' << b << '\n';

  c.change(4);
  std::cout << a << ' ' << b << '\n';
}

查看它在Coliru上实时运行,它打印:

1 1
2 2
3 3
4 4

3
投票

您不能使用对对象的常量引用来更改对象,但是如果对象不是常量或使用对对象的非常量引用,则可以更改对象本身。

请考虑以下演示程序。

#include <iostream>

int main() 
{
    int x = 10;

    int &rx = x;
    const int &crx = x;

    std::cout << "rx = " << rx << '\n';
    std::cout << "crx = " << crx << '\n';

    rx = 20;

    std::cout << "rx = " << rx << '\n';
    std::cout << "crx = " << crx << '\n';

    return 0;
}

其输出为

rx = 10
crx = 10
rx = 20
crx = 20

与使用指向常量数据的指针相同。例如

#include <iostream>

int main() 
{
    int x = 10;

    int *px = &x;
    const int *cpx = &x;

    std::cout << "*px = " << *px << '\n';
    std::cout << "*cpx = " << *cpx << '\n';

    *px = 20;

    std::cout << "*px = " << *px << '\n';
    std::cout << "*cpx = " << *cpx << '\n';

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.