![](/img/trans.png)
[英]Why can I call a non-const member function pointer from a const method?
[英]Why am I allowed to call a non-const member function from a const_iterator if the container element is a pointer?
请考虑以下代码:
#include <vector>
using namespace std;
struct foo
{
void bar()
{
}
};
int main()
{
{
vector<foo*> a;
a.push_back(new foo());
a.push_back(new foo());
a.push_back(new foo());
vector<foo*>::const_iterator itr = a.begin();
(*itr)->bar(); // compiles - this becomes more confusing
// when found in a const method. On first
// glance, one will (or at least me) may
// assume that bar() must be const if the
// method where it is being called from is
// const
// The above compiles because internally, this is what happens
// (ignore the fact that the pointer has not been newd)
foo* const * element;
(*element)->bar(); // compiles
// What I would expect however (maybe it is just me) is for const_iterator
// to behave something like this
const foo* const_element;
const_element->bar(); // compile error
}
{
vector<foo> a;
a.resize(10);
vector<foo>::const_iterator itr = a.begin();
itr->bar(); // compile error
}
}
我理解为什么可以这样称呼它。 const_iterator
存储const-ness,如下所示: const T*
,指针转换为foo* const *
,对象为foo const *
。
所以我的问题是,为什么我们允许从const_iterator
调用非const成员函数? 不允许从const_iterator
调用非const成员函数更直观吗? 不应该使用const选项设计iterator
防止这种行为吗?
现在更重要的问题是: 如果我希望const_iterator
禁止调用指向对象的非const成员函数,该怎么办?
不应该使用const选项设计迭代器来防止这种行为吗?
确实如此。 你只是期望它是一个不同的操作。
正如您所发现的,指针容器......包含指针 ,而不是对象。 因此,这样的指针的const_iterator
意味着指针是常量,而不是它们指向的对象。
这不会改变,也不会改变。 标准库容器通常设计为包含完整的对象,而不是指针。 所以他们不应该鼓励用户制作指针和其他可疑构造的vector
。
如果你真的需要一个包含指针的vector
,那么你应该使用一个实际设计的容器。 就像Boost的指针容器类一样 。 他们的const_iterators
使对象正确地指向const
。 他们还做其他有用的事情,比如拥有他们指向的对象(以便正确删除它们)等等。
你有一个指针向量,指针没有成员函数,因此你不会在存储在向量中的东西上调用成员函数。
取消引用指针时获得的对象类型取决于该指针的类型。 您的向量是非常量指针的向量,因此当您从容器中解除任何指针时,您总是会获得对指向对象的非常量引用。
如果你想要一个指针矢量,那么你有两个选择。 你可以创建一个vector<const foo*>
,你将永远无法检索对任何指向对象的指针的非const引用,或者,如果你需要能够从你的非const实例获得非const引用向量您必须创建一个包含向量作为私有成员变量的对象,并通过传递接口为您提供所需的访问权限。
如果你的向量应该拥有它保存指针的对象,你可以考虑使用简单的vector<foo>
或者如果需要动态分配,则可以考虑使用boost::ptr_vector<foo>
。
所以我的问题是,为什么我们允许从const_iterator调用非const成员函数?
“常量迭代器”表示容器元素是常量。 这并不意味着如果该元素是指针,则指向的对象也是常量。
如果我希望const_iterator禁止调用指向对象的非const成员函数,该怎么办?
我不想鼓励你使用像这样的原始指针,但是如果你真的必须这样做,那就把它作为指向const对象的指针的容器。
std::vector<const foo*> a;
// ...
auto itr = a.cbegin();
(*itr)->bar(); // Compiler error (calling a non-const method on const object).
当然,在这种情况下,以下情况也是不允许的:
std::vector<const foo*> a;
// ...
auto itr = a.begin();
(*itr)->bar(); // Compiler error.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.