为什么即使写一次也会重复应用T* operator->()
?但是另一个T& operator*()
被应用一次,应该写多次。
众所周知,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)中有什么相关内容吗?
更新
在不同的情况下,我们应该使用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运营商 - &gt;应该是一个不带参数的非静态成员函数。它实现了 使用 - &gt;的类成员访问语法。 postfix-expression - &gt; templateopt id-expression postfix-expression - &gt;伪析构函数名 表达式x-> m被解释为(x.operator-&gt;()) - &gt; m表示类 如果T :: operator-&gt;()存在且操作符是,则类型为T的对象x 通过重载决策选择最佳匹配函数 机制(13.3)。
即。 x->m
为(x.operator->())->m
。
答案 0 :(得分:2)
a->b
是指针时, (*a).b
被定义为a
。
如果a
不是指针,则将其定义为(a.operator->())->b
。现在通常operator->
返回一个指针,然后执行(*(a.operator->())).b
并完成。
但如果它返回一个非指针,则该定义是递归的。
对于一元operator*
没有类似的递归定义。
简而言之,标准就是如此。为什么?因为作家认为它既优雅又实用。
顺便说一句,operator.
有一个活跃的提案,可能会在2021年使用C ++。这样就可以使(*a).b
的行为与a->b
相同。
答案 1 :(得分:1)
以下两个案例分解了一些:
(*vecc)->push_back(30); // 3. ok
VisualizableVector::proxy proxy3 = vecc.operator*();
std::vector<int> *pointer = proxy3.operator->();
pointer->push_back(30);
(**vecc).push_back(50); // 5. ok
VisualizableVector::proxy proxy5 = vecc.operator*();
std::vector<int> &reference = proxy5.operator*();
reference.push_back(50);
你需要用*取消引用两次的原因是因为proxy :: operator *()返回一个指向底层类型的指针。
如果有指针,可以直接使用“ - &gt;”调用其成员或者您可以用“*”取消引用它,然后使用“。”无论指针来自何处,都是如此。
由于你从*获得指针,并且你在该指针上使用*,这就是你使用两个*的原因。