运算符。*()做什么?

时间:2015-02-25 13:08:13

标签: c++ operators

operator.*()做什么?它的目的是什么?

它记录为Pointer-to-member,与->*完全相同。那两个相同吗?

Scott Meyers在更有效的C ++中,第7项解释了.*不可重载,而->*是。那是为什么?

4 个答案:

答案 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之间的整数。