【问题标题】:What exactly is a const variable?const 变量到底是什么?
【发布时间】:2014-10-03 08:42:58
【问题描述】:

我了解const 指针。但是我不完全理解const 普通变量。

const int a

我理解上面的陈述,因为它是一个原始的。所以它只能意味着一件事:a 的值不能改变。

但是这个呢?

const Car car

这可能意味着以下两种情况之一:

A- 变量car 的值无法更改。也就是说,我不能在里面放一个不同的Car

B- 此变量所持有的对象本身不能更改。即,我们无法更改此变量中对象的状态。

以下哪一项是正确的?

【问题讨论】:

    标签: c++ variables constants


    【解决方案1】:

    两者。

    因为The value of variable carthe state of the object that's inside this variable 是同一个东西。

    一个对象只不过是它的成员的集合。

    【讨论】:

      【解决方案2】:

      两个都是正确的:

      A- 变量 car 的值不能改变。也就是说,我不能在里面放一辆不同的车。

      您将无法将任何其他 Car 类实例分配给 car。如果您使用的是 java,那么这与分配对新变量的引用不同,在 c++ 中,在这种情况下会复制整个对象。

      B- 此变量所持有的对象本身不能更改。即,我们无法更改此变量中对象的状态。

      它是正确的,因为您将只能调用 const 方法,这些方法也不允许修改字段,除非它们被标记为可变。

      【讨论】:

        【解决方案3】:

        这不是一个完全直截了当的问题。具体来说,将car 设为const 会使编译器将car 的所有非可变成员视为const。它还可以防止您在 car 上调用非常量成员函数。

        将成员视为 const 是什么意思?嗯,这取决于它的类型。如果它是一个指针,它是指针而不是被视为 const 的指针。假设我们有以下类:

        class C
        {
        public:
          Foo foo;
          Bar *bar;
          mutable Baz baz;
        
          void nc()
          {
            foo = ...;  // fine
            bar = ...;  // fine
            *bar = ...; // fine
            baz = ...;  // fine
          }
        
          void c() const
          {
            foo = ...;  // not fine
            bar = ...;  // not fine
            *bar = ...; // fine
            baz = ...;  // fine
          }
        };
        
        const C c;
        c.foo = ...;  // not fine
        c.bar = ...;  // not fine
        *c.bar = ...; // fine
        c.baz = ...;  // fine
        c.nc();       // not fine
        c.c();        // fine
        

        如果你有一个C 的 const 实例,你就可以在它上面调用 const 成员函数。您(取决于访问)或那些 const 成员函数也可以更改 bar 和实际对象 baz 指向的东西,但不能更改 foobar,因为编译器会处理 @987654330 @ 类型为 const Foobar 类型为 Bar *constbaz 类型为 Baz

        为了直接解决您的问题,A 和 B 都是对正在发生的事情的大致正确的看法,但都没有很好地捕捉到真实情况,不足以作为问题的答案。

        特别是,A(本质上说您不能分配给 const 对象)是一种简化,因为可以(可能不明智,但可能)编写一个仅分配给可变成员或指针的赋值运算符。

        B 是一种简化,因为它没有考虑到类中可能存在的可变成员。根据您所说的“状态”的含义,它更接近于事实,因为可变成员通常用作私有实现的一部分,并且不代表类的逻辑状态的一部分,但它仍然不是很准确。

        【讨论】:

          【解决方案4】:

          两者都是正确的。将新的Car 分配给car 是通过调用Car::operator=(Car const& other) 完成的,无论是显式实现还是编译器生成。这反过来又会从other 的成员中分配car 的所有成员。所以赋值改变状态的。

          由于困惑,我想知道您是否更习惯于像 C# 或 Java 这样具有引用类型对象变量而不是对象类型变量的语言。在那里(就像 C++ 中的指针一样),分配给变量与更改其状态不同,因为存储在 car 中的原始 Car 仍然存在于某个地方,没有改变。但是对于值类型的对象变量,您并没有真正将“不同的Car 放入其中”——您正在更改原始的Car,使其看起来与新的Car 相同。

          【讨论】:

          • 你的意思是Car::operator=(...
          • @BartvanNierop 我不知道你在说什么。 :-D(谢谢)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-18
          • 2015-06-16
          • 1970-01-01
          相关资源
          最近更新 更多