C++ C++;非常量指针成员上的常量方法
我想知道如何通过const方法保护非const指针成员不受对象的影响。例如:C++ C++;非常量指针成员上的常量方法,c++,pointers,object,methods,constants,C++,Pointers,Object,Methods,Constants,我想知道如何通过const方法保护非const指针成员不受对象的影响。例如: class B{ public: B(){ this->val=0; } void setVal(){ this->val = 2; } private: int val; }; class A{ public: A():b(new B
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数据?
经过大量的网络研究,目前还没有令人满意的结果
感谢您的帮助。如果您从
B* b;
到
然后您将获得预期的行为
class A{
public:
A() : b() {}
void changeMemberFromConstMethod() const{
this->b.setVal(); // This will produce a compiler error.
}
private:
B b;
}
问题是
const
方法使所有成员变量const
。但是,在这种情况下,它会使指针常量
。具体地说,就好像你所拥有的就是B*const B
,这意味着一个指向(仍然)可变B
的常量指针。如果不将成员变量声明为const B*B
,(即指向常量B
)的可变指针,则无法防止这种行为
class A{
public:
A() : b() {}
void changeMemberFromConstMethod() const{
this->b.setVal(); // This will produce a compiler error.
}
private:
B b;
}
如果您只需要一个常数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
不会在A
的常量中变异,比如:
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;
};
模板
类深常数{
T*p_;
公众:
深常数ptr(T*p):p(p);
T*运算符->(){return p_;}
常量T*运算符->()常量{return p_;}
};
甲级{
深常数b=新b;
};
deep_const_ptr
在a
的常量方法中的行为类似于const T*const
指针,在非常量方法中的行为类似于T*
。进一步充实类是读者的一项练习。在这种情况下,尝试使用以下通用方法来保护通过指针引用的对象的常量
重命名为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指针,重命名的额外步骤确保所有现有代码都必须遵守新的规则。“医生,我这样做很痛苦”-“所以不要这样做。”
这不像是有人扭动你的手臂,强迫你从const方法调用setVal
。我想我不明白这个问题的本质,只是举个例子。例如,它就像我要设置的保证,即不修改指向的B数据。如果你不想修改*B
,那么就不要修改。我仍然无法理解困难的本质。首先感谢您的早期回答。我的问题的本质是关于通过const进行语义保护。如果b是一个对象,编译失败,这是正常的。我想保证这种行为。你看到了吗?我知道如果我不想修改*b我不会。只是举个例子。我猜他想看到执行上述代码的错误消息。我同意你的看法。但是如果我设置:void changemberfromConstMethod(){b->setVal();},另一方面这将失败。我希望const方法说:const B*B const;你看,这是一个有趣的方法。但它有点扭曲。如何根据const或not method找到正确的方法?const方法只能调用其他const方法。在常量方法中,“this”是常量指针,而不是可变指针。这确实是一种相当常见的设计模式。它很有趣!但是如何选择正确的操作符呢?我几乎明白了。它如何更精确地工作(分辨率)。它将尝试第一个运算符,并查看返回值是否为常量,并将找到正确的另一个运算符?就这样?不,重载解析(大多数情况下)不会查看返回类型。但它确实会检查该方法是否标记为const
。在常量对象上调用时,非常量方法不可行,因此只能使用常量方法。在非常量对象上调用时,首选非常量方法。非常感谢。你是怎么知道这些深层力学的最后,你明白我问题的目的和语义方式了吗?