我想知道如何通过const方法保护非const指针成员免受对象的影响。例如:
class B{
public:
B(){
this->val=0;
}
void setVal(){
this->val = 2;
}
private:
int val;
};
class A{
public:
A():b(new B){}
void changeMemberFromConstMethod() const{
this->b->setVal();
}
private:
B * b; // how to protect data pointed in A::changeMemberFromConstMethod
}
是否有可能"保护"从他的方法指出A :: b数据? 经过对网络的多次研究,尚未发现满意的反应。
感谢您的帮助。
答案 0 :(得分:10)
这样的事情,也许是:
template <typename T>
class deep_const_ptr {
T* p_;
public:
deep_const_ptr(T* p) : p_(p);
T* operator->() { return p_;}
const T* operator->() const { return p_;}
};
class A {
deep_const_ptr<B> b = new B;
};
deep_const_ptr
在const T* const
的const方法中表现得像A
指针,在非const方法中表现得像T*
。进一步充实课堂留给读者练习。
答案 1 :(得分:6)
如果您从
更改A
的成员
B* b;
到
B b;
然后你会得到预期的行为。
class A{
public:
A() : b() {}
void changeMemberFromConstMethod() const{
this->b.setVal(); // This will produce a compiler error.
}
private:
B b;
}
答案 2 :(得分:4)
您遇到的问题是const
方法会生成所有成员变量const
。但是,在这种情况下,它会使指针const
。具体来说,就好像你只有B * const b
,这意味着一个指向(仍然)可变B
的常量指针。如果您没有将您的成员变量声明为const B * b
,(即,指向常量B
的可变指针),则无法保护此行为。
如果您只需要const B
,那么请务必定义A
,如下所示:
class A {
public:
A() : b(new B) {}
// This WILL give an error now.
void changeMemberFromConstMethod() const { b->setVal(); }
private:
const B* b;
}
但是,如果A
的其他方法发生变异B
,那么您所能做的就是确保B
的{{1}}方法不会突变const
1}}。
答案 3 :(得分:1)
在这种情况下,尝试使用以下一般方法来保护通过指针引用的对象的常量。
重命名B * b
B *my_pointer_to_b;
并相应地更改构造函数中的初始化。
实现两个存根:
B *my_b() { return b; }
const B *my_b() const { return b; }
在现有代码中用my_b()替换b的所有现有引用。接下来,在任何新代码中,总是使用my_b()将指针返回到b。
可变方法将得到一个非常量指向B的指针; const方法将得到一个指向B的const指针,并且重命名的额外步骤确保所有现有代码都被强制遵守新制度。