operator.*()
做什么?它的目的是什么?
它记录为Pointer-to-member,与->*
完全相同。那两个相同吗?
Scott Meyers在更有效的C ++中,第7项解释了.*
不可重载,而->*
是。那是为什么?
答案 0 :(得分:3)
已经回答过,不,.*
和->*
并不代表同一件事。假设没有使用重载运算符,a->*b
表示(*a).*b
,即.*
用于类类型,->*
用于指向类类型的指针。如果使用内置运算符,就像a->b
的含义(*a).b
一样。
.
和.*
都不会超载,因为不清楚标准何时写入是否会产生负面影响。 .
更有用,is still being considered for a future version of C++,但是第一个提出可重载dates back to 1990的提议(早在第一个C ++标准发布之前)。需要解决的一些问题涉及选择a.b
对内置运算符有效时要执行的操作,但不有效为(伪代码)(a.operator.()).b
。然后内置运算符会在其位置使用,还是应该是错误?似乎都不是特别理想。
重载.
运算符的一些提议还包括重载.*
运算符,其他运算符则不包括.*
运算符。没有那么多要求让.
本身可以超载,所以如果它确实在某个时候被接受,它可能会与{{1}}一起发生,并且这需要很长时间
答案 1 :(得分:2)
它设计用于:
类类型的左操作数
指向此类类型的"成员的指针的右操作数"
#include <iostream>
#include <string>
using std::string;
class Foo{
public:
int f(string str){
std::cout<<"Foo::f()"<<std::endl;
return 1;
}
};
int main(int argc, char* argv[]){
int (Foo::*fptr) (string) = &Foo::f;
Foo obj;
(obj.*fptr)("str");//call: Foo::f() through an object
Foo* p=&obj;
(p->*fptr)("str");//call: Foo::f() through a pointer
}
请注意,我没有制作此代码,它来自一个解释它是如何工作的教程,但实际上并不是什么目的
关于过载能力的差异是相同的。和 - &gt;,所以它并不特别针对这种情况,并且像this one
一样受到关注 委员会决定这些事情,而不是每一次都有明显的理由,但这与x-&gt;这一事实是一致的。可以看作(* x)。, 。()不能重载,但*()可以,所以这些组合暗示 - &gt;可以超载,因为&#34;它的一部分有不同的写作&#34;可以超载我最后说的只是我的想法,试图继续欣赏c ++的美丽和连贯性
答案 2 :(得分:0)
它的指针是一个成员。例如:
// This functions waits until predicate evalues false
void waitSomething(bool (one_class::*predicate)(),one_class& that)
{
while ((that.*predicate)())
{
sleep(100);
}
}
你可以打电话给:
one_class a;
waitSomething(&a::*predicate,a); //predicate is an internal function member
您也可以使用属性。
- &gt; *用于指针:
// This functions waits until predicate evalues false
void waitSomething(bool (one_class::*predicate)(),one_class* that)
{
while ((that->*predicate)())
{
sleep(100);
}
}
答案 3 :(得分:-1)
我不确定这对你是否特别有帮助,但这是我从你的问题中学到的。
将运算符->*
(which is a real thing…)与运算符->
一起重载的合理用例可能是提供对托管对象的透明访问(考虑std::unique_ptr
)也用于间接成员访问。但请注意,std::unique_ptr
会重载运算符->
,但不会重载运算符->*
。
就像我们不能重载运算符.
一样,我们也不能重载运算符.*
,因为it was decided to be like this。
所以这里有一个有点愚蠢的类,它包装一个对象并假装成一个指向它的指针。如果托管对象由具有托管生命周期的指针持有,那么该示例会更有意义,但我希望避免使用与成员访问无关的资源管理代码来混淆示例。
// C++14
#include <iostream>
#include <utility>
#include <vector>
template<typename T>
class PointerLike
{
private:
T object_;
public:
template<typename... ParamT>
PointerLike(ParamT&&... params) : object_ {std::forward<ParamT>(params)...}
{
}
// The 'const' overloads have been omitted for the sake of brevity.
// "Dereferences" the handle and obtains a reference to the managed object.
T&
operator*()
{
return this->object_;
}
// Accesses a member of the managed object.
T *
operator->()
{
return &(this->object_);
}
// Indirectly invokes a function member of the managed object.
template<typename RetT, typename... ArgT>
decltype(auto)
operator->*(RetT(T::*mfunc)(ArgT...))
{
return [=](ArgT... args)->RetT{
return (object_.*mfunc)(std::forward<ArgT>(args)...);
};
}
};
int
main()
{
typedef std::vector<int> ivec;
typedef void (ivec::*append_member_type)(int&&);
append_member_type append = &ivec::push_back;
PointerLike<ivec> pl {1, 2, 3, 4};
pl->push_back(5); // pointer-like direct member access
(pl->*append)(6); // pointer-like indirect member access ("natural" way)
((*pl).*append)(7); // pointer-like indirect member access
for (const auto& v : *pl)
std::cout << v << std::endl;
}
程序将输出1到7之间的整数。