为什么我可以从 const 方法调用更改成员的方法?
Why can I call a method that changes a member from a const method?
我不太明白为什么我可以从 const 方法修改一个对象,请看:
#include <iostream>
struct Foo {
int a = 0;
void change() {
a = 3;
}
};
struct Test {
Foo* f;
Test(): f{new Foo} {}
void test() const {
f->change();
}
};
int main()
{
Test t;
std::cout << "before: " << t.f->a << "\n";
t.test();
std::cout << "after: " << t.f->a << "\n";
}
不仅编译而且打印:
0
3
所以我能够从 const 方法修改对象的逻辑状态。那是因为我使用了指针吗?
const
适用于指针本身,f
,不适用于此指针指向的对象。 const
限定成员函数 Test::test()
中 f
的类型是 Foo* const
(即 const
指向 Foo
),而不是 const Foo*
(即 指向 const Foo
的指针)。这就是为什么你可以修改指针指向的内容,尽管成员函数的 const
限定。
请注意,以下示例成员函数 Test::test2()
确实无法编译,因为它是 const
限定的并尝试修改指针数据成员 f
:
void Test::test2() const {
f = nullptr; // <-- error
}
不,您没有修改对象的逻辑状态:
f->change();
f
,对象的 class 成员,一如既往地在这里。它的值没有改变。它现在不指向其他对象。它仍然指向它一直指向的同一个对象。
你修改的是f
指向的对象。这是一个不同的对象。
是的,您修改了对象的逻辑状态。这是允许的,因为 const
禁止修改 physical 状态。
对象 t
有一个数据成员 f
,类型为 "pointer to Foo"。创建 t
对象时,它的 f
成员指向类型 Foo
的对象。在调用 t.test()
之后,f
成员仍然持有相同的地址,因此它指向与之前相同的 Foo
类型的对象。
如果test()
试图改变存储在f
中的值(即指针),const
会阻止它.
void Test::test() const { f = new Foo; } // error: `f` is const in this context
我不太明白为什么我可以从 const 方法修改一个对象,请看:
#include <iostream>
struct Foo {
int a = 0;
void change() {
a = 3;
}
};
struct Test {
Foo* f;
Test(): f{new Foo} {}
void test() const {
f->change();
}
};
int main()
{
Test t;
std::cout << "before: " << t.f->a << "\n";
t.test();
std::cout << "after: " << t.f->a << "\n";
}
不仅编译而且打印:
0
3
所以我能够从 const 方法修改对象的逻辑状态。那是因为我使用了指针吗?
const
适用于指针本身,f
,不适用于此指针指向的对象。 const
限定成员函数 Test::test()
中 f
的类型是 Foo* const
(即 const
指向 Foo
),而不是 const Foo*
(即 指向 const Foo
的指针)。这就是为什么你可以修改指针指向的内容,尽管成员函数的 const
限定。
请注意,以下示例成员函数 Test::test2()
确实无法编译,因为它是 const
限定的并尝试修改指针数据成员 f
:
void Test::test2() const {
f = nullptr; // <-- error
}
不,您没有修改对象的逻辑状态:
f->change();
f
,对象的 class 成员,一如既往地在这里。它的值没有改变。它现在不指向其他对象。它仍然指向它一直指向的同一个对象。
你修改的是f
指向的对象。这是一个不同的对象。
是的,您修改了对象的逻辑状态。这是允许的,因为 const
禁止修改 physical 状态。
对象 t
有一个数据成员 f
,类型为 "pointer to Foo"。创建 t
对象时,它的 f
成员指向类型 Foo
的对象。在调用 t.test()
之后,f
成员仍然持有相同的地址,因此它指向与之前相同的 Foo
类型的对象。
如果test()
试图改变存储在f
中的值(即指针),const
会阻止它.
void Test::test() const { f = new Foo; } // error: `f` is const in this context