7

我知道这已经被问了很多,但我能找到的唯一答案是当使用 (int*) 或类似方法实际抛弃 const-ness 时。当不涉及强制转换时,为什么 const 限定符不适用于 const 对象上的指针类型成员变量?

#include <iostream>

class bar {
public:
    void doit()       { std::cout << "    bar::doit() non-const\n"; }
    void doit() const { std::cout << "    bar::doit() const\n"; }
};

class foo {
    bar* mybar1;
    bar mybar2;
public:
    foo() : mybar1(new bar) {}
    void doit() const {
        std::cout << "foo::doit() const\n";
        std::cout << "  calling mybar1->doit()\n";
        mybar1->doit();  // This calls bar::doit() instead of bar::doit() const
        std::cout << "  calling mybar2.doit()\n";
        mybar2.doit(); // This calls bar::doit() const correctly
    }
    // ... (proper copying elided for brevity)
};

int main(void)
{
    const foo foobar;  // NOTE: foobar is const
    foobar.doit();
}

上面的代码产生以下输出(在 gcc 4.5.2 和 vc100 中测试):

foo::doit() 常量
  调用 mybar1->doit()
    bar::doit() 非常量 <-- 为什么?
  调用 mybar2.doit()
    bar::doit() 常量
4

3 回答 3

15

当 foo 实例是 const 时,它的数据成员也是 const ,但这适用于指针的情况与您最初可能认为的不同:

struct A {
  int *p;
};

A const obj;

obj.p 的类型是 int * const,而不是 int const *;也就是说,指向 int 的常量指针,而不是指向常量 int 的指针。

对于另一种看待它的方式,让我们从一个函数开始:

template<class T>
T const& const_(T const &x) {
  return x;
}

现在假设我们有一个 A 实例,我们将其设为 const。您可以将其想象为在每个数据成员上应用 const_ 。

A nc;
// nc.p has type int*.
typedef int *T;  // T is the type of nc.p.

T const &p_when_nc_is_const = const_(nc.p);
// "T const" is "int * const".

const T &be_wary_of_where_you_place_const = const_(nc.p);
// "const T" is "int * const".
// "const T" is *not* "const int *".

变量 be_wary_of_where_you_place_const 表明“添加 const”在类型的文字文本前添加“const”不同。

于 2011-05-06T22:30:05.757 回答
1

在这种情况下,我将回答我自己的问题。Fred Nurk 的回答是正确的,但并没有真正解释“为什么”。mybar1并且*mybar1是不同的。第一个指的是实际的指针,后者指的是对象。指针是 const (正如 foo 上的 const-ness 所要求的;你不能这样做mybar1 = 0),但不是指向对象,因为这需要我声明它const bar* mybar1。声明bar* mybar1等价于bar* const mybar1foo 对象为 const 时(即指针为 const,未指向对象)。

于 2011-05-06T23:13:00.457 回答
0

默认情况下,C++ 提供所谓的按位常量——这意味着它确保没有任何一位对象被更改,因此它只检查指针的地址。

您可以在 S. Meyers 的《Effective c++》一书中了解更多相关信息

于 2014-04-30T16:05:37.717 回答