可变在C++常量指针
如果我使用mutable
与const
指针这样的:可变在C++常量指针
class Test
{
public:
mutable const int* ptr; // OK
};
它的正常工作。
但是,如果我用这样的:
class Test
{
public:
mutable int * const ptr; // Error
};
错误:
prog.cpp:6:25: error: const 'ptr' cannot be declared 'mutable'
mutable int * const ptr;
^
prog.cpp: In function 'int main()':
prog.cpp:11:7: error: use of deleted function 'Test::Test()'
Test t;
^
prog.cpp:3:7: note: 'Test::Test()' is implicitly deleted because the default definition would be ill-formed:
class Test
^
prog.cpp:3:7: error: uninitialized const member in 'class Test'
prog.cpp:6:25: note: 'int* const Test::ptr' should be initialized
mutable int * const ptr;
为什么编译器给在第二种情况下的错误?
第二种情况会导致错误,因为mutable
和const
不能混合; mutable
只能与非常量数据成员一起使用。
适用于非参考非常量类型的非静态类成员,并指定该成员不影响类的外部可见状态(如常用于互斥,备忘缓存,延迟评估和访问工具)。 const类实例的可变成员是可修改的。
顺便说一句,下面的代码会导致相同的错误。
class Test
{
public:
mutable const int x; // Error;
mutable int const x; // ditto;
};
的第一种情况是好的,因为const int*
不是const
指针,但指针const
。这意味着可以修改指针本身,并且可以将其标记为mutable
。 (但是,您不能修改指针。)
指针const
(例如mutable const int* const ptr;
)也会导致相同的错误。
第一个是指向常量数据的指针,这意味着您可以更改指针以及它指向的位置,但不能更改它指向的数据。
第二个是常量指针为非常量数据,这意味着您必须在构造函数中初始化指针,然后无法将其指向其他任何位置。它指向的数据可以修改。
的mutable
部分在这两种情况下适用于指针,实际成员变量,不是指向数据。而且由于变量不能同时变为可变和常量,所以你应该得到一个错误消息。
struct Test
{
const int* ptr;
};
翻译:“该结构具有一个部件的部件是一个指示器指针指向其可以不经由指针被突变的整数”
本身可以虽然突变,该指针指向一个不同const int
。
如果我们选择一个非引用类型,这可能会更简单,因此您可以从指向对象的类型中分离出成员的类型(在您的示例中为指针)。现在
struct Test1
{
int value;
};
,加入mutable
关键字,以得到
struct Test2
{
mutable int value;
};
只是意味着我们允许发生变异的成员即使在结构本身,否则常量。
换句话说,所有这一切都在这两种情况下是OK:
Test1 a { 123 };
Test2 b { 123 };
// now mutate the object through a non-const reference
a.value = 42;
b.value = 42;
但这是不同的:
const Test1& ca = a;
ca.value = 69; // NO, a member of a const object is const
const Test2& cb = b;
cb.value = 69; // OK, a mutable member of a const object
所以,现在我们理解正在如何可变的应用中,考虑问题线:
mutable int * const ptr;
这就是说ptr
是均为 mutable(即使其对象的成员为const成员也可以进行变异)和 const(即使当它是其成员的对象是非const的时候也不能被突变)。
两个显然是矛盾的。
是什么错误消息说?这可能值得一读。 – VTT
@VTT http://ide.geeksforgeeks.org/PWB4ti – Jayesh
*编辑您的问题*以包含构建错误。作为文本逐字复制粘贴,全部完整。 –