即使写入一次,为什么T* operator->()
会重复应用?但另一个T& operator*()
应用一次,并且应该写很多次。即使写入一次,为什么`T *运算符 - >()`被重复应用?
众所周知,C++中有Execute-Around Pointer Idiom。 More C++ Idioms/Execute-Around Pointer
提供一个智能指针对象,该对象在每个对象的每个函数调用之前和之后都透明地执行动作,前提是所执行的操作对所有函数都是相同的。并且对每一个治疗前后的成员变量进行一次处理。例如,我们可以执行:
- 锁定互斥
- 日志动作
- 可视化改变数据
我加了一些在main()
到this example:
#include <iostream>
#include <vector>
class VisualizableVector {
public:
class proxy {
public:
proxy (std::vector<int> *v) : vect (v) {
std::cout << "Before size is: " << vect->size() << std::endl;
}
std::vector<int> * operator ->() { return vect; }
std::vector<int> & operator *() { return *vect; }
~proxy() { std::cout << "After size is: " << vect->size() << std::endl; }
private:
std::vector <int> * vect;
};
VisualizableVector (std::vector<int> *v) : vect(v) {}
~VisualizableVector() { delete vect; }
proxy operator ->() { return proxy (vect); }
proxy operator *() { return proxy (vect); }
private:
std::vector <int> * vect;
};
int main()
{
VisualizableVector vecc (new std::vector<int>);
vecc->push_back (10); // 1. Note use of -> operator instead of . operator
vecc->push_back (20); // 2. ok
(*vecc)->push_back (30); // 3. ok
// (*vecc).push_back (40); // 4. error
(**vecc).push_back (50); // 5. ok
// vecc->->push_back (60); // 6. error
}
在线编译结果: http://ideone.com/cXGdxW
为什么我们需要写两次**
,但只有一次->
?
其经营者返回相同的事情proxy
:
proxy operator ->() { return proxy (vect); }
proxy operator *() { return proxy (vect); }
,但为什么我们需要再次使用*
,但我们不应该再次使用->
?:
vecc->push_back (20); // 2. ok (vecc->) is proxy
(**vecc).push_back (50); // 5. ok (*vecc) is proxy
为什么不vecc->->push_back (20);
?
在标准C++(03/11/14)中有什么关于这个的吗?
UPDATE:
在不同情况下,我们应该使用1,2或3 operator->
S:http://ideone.com/89kfYF
#include <iostream>
#include <vector>
class VisualizableVector {
public:
class proxy {
public:
proxy (std::vector<int> *v) : vect (v) {
std::cout << "Before size is: " << vect->size() << std::endl;
}
std::vector<int> * operator ->() { return vect; }
std::vector<int> & operator *() { return *vect; }
~proxy() { std::cout << "After size is: " << vect->size() << std::endl; }
private:
std::vector <int> * vect;
};
VisualizableVector (std::vector<int> *v) : vect(v) {}
~VisualizableVector() { delete vect; }
proxy operator ->() { return proxy (vect); }
proxy operator *() { return proxy (vect); }
private:
std::vector <int> * vect;
};
int main()
{
VisualizableVector vecc (new std::vector<int>);
vecc->push_back(30); // ok // one ->
//vecc.operator->().push_back(30);// error // one ->
//vecc->->push_back(30); // error // two ->
vecc.operator->()->push_back(30); // ok // two ->
auto proxy3 = vecc.operator->(); // 1st operator->()
auto pointer = proxy3.operator->(); // 2nd operator->()
pointer->push_back(30); // 3rd operator->()
return 0;
}
页面327:Working Draft, Standard for Programming Language C++ 2014-11-19
13.5.6类的成员访问[over.ref] 1 operator->应该是一个不带参数的非静态成员函数。它实现了使用 - >的 类成员访问语法。 postfix-expression - > templateopt id-expression postfix-expression - > pseudo-destructor-name 表达式x-> m被解释为(x.operator - >()) - > m对于类 对象x的类型T如果T :: operator - >()存在,并且运算符 被过载分辨率 机制(13.3)选为最佳匹配函数。
I.e. x->m
是(x.operator->())->m
。
简短的回答是:因为这就是C++的工作原理,因为这就是你编写类工作的方式。 –
注意:这是一个不好的问题,因为不需要使用'new'(没有配对'delete') –
恕我直言,'operator->'和'operator *'返回完全相同的类型,本身就不好。 –