Aru*_*run 23 c++ pointers const transitive-const
请考虑以下代码段:
class A
{
public:
void nonConstFun()
{
}
};
class B
{
private:
A a_;
A * pA_;
public:
void fun() const
{
pA_->nonConstFun();
//a_.nonConstFun(); // Gives const related error
}
};
int main()
{
B b;
b.fun();
}
Run Code Online (Sandbox Code Playgroud)
在这里,我期望编译器在编译时因为缺少常量来调用A::nonConstFun()
内部,B::fun()
而不管A对象的类型如何.
但是编译器会抱怨该对象,而不是指针.为什么?我在Windows 10上使用VS2017.
bol*_*lov 52
其他答案解释了T* const
vs T const *
正在发生的事情.但重要的是要理解这不仅仅是单纯的语法.
当你有一个T*
结构内部时,指针在对象内部,但指向的对象在物理上位于结构之外.这就是为什么对于带有T*
成员的const对象,不允许修改指针,但允许修改指向对象 - 因为物理上指向的对象在封闭对象之外.
并且由程序员决定指向的对象是否在逻辑上是封闭对象的一部分(因此应该与封闭对象共享const)或者逻辑上是否是外部实体.
C++的缺点在于它没有提供一种简单的方法来表达上面所述的逻辑常量(你实际对代码的期望).
这是已知的,并且出于这个确切的目的,存在尚未标准的实验类 propagate_const
std :: experimental :: propagate_const是指针和类指针对象的const传播包装器.当通过const访问路径访问时,它将包装指针视为指向const的指针,因此命名.
struct B
{
A a_;
std::experimental::propagate_const<A *> pA_;
void fun()
{
pA_->nonConstFun(); // OK
}
void fun() const
{
// pA_->nonConstFun(); // compilation error
}
};
Run Code Online (Sandbox Code Playgroud)
Lig*_*ica 43
它是强制执行的.
如果您尝试更改指针,编译器将不会让您.
然而,指针所指向的是一个不同的对话.
请记住,T* const
并且T const*
是不一样的东西!
您可以通过实际制作它A const*
,或者仅仅通过以适当的方式编写您的功能来保护它.
归档时间: |
|
查看次数: |
3216 次 |
最近记录: |