开发者

overloading virtual operator -> ()

This is just an experi开发者_运维知识库ment code.

struct B
{
  virtual B* operator -> () { return this; }
  void foo () {} // edit: intentionally NOT virtual
};

struct D : B
{
  virtual D* operator -> () { return this; }
  void foo () {}
};

int main ()
{
  B &pB = *new D;
  pB->foo();  // calls B::foo() !
}

I know that operator has to be called using object or reference; thus in above case does reference pB still resolute to the object of B ? Though it will not be practical, but for curiosity, is there any way to invoke D::operator -> through pB ?


I think it is invoking D::operator->, but the return value is being treated as a B*, so B::foo() is being called.

This is an artifact of how covariant return types behave.


pB is of type B&. Hence any method (such as operator->) invoked on it will get the signature in B, therefore pB.operator->() will return a B*. Of course, because it's virtual, the actual implementation in D is used. The important thing is that the return type is defined by the type of the pB variable.

So, our operator-> has returned a B*, and therefore invoking foo() proceeds as with any other B*.


It doesn't matter which operator it invokes (which in this case is probably D::operator->), what matters is the this. In this case the this pointer is of type B*, so the foo call is dereferenced to B::foo. If it was virtual - it would work correctly, but you intentionally didn't make it virtual...


Virtual member functions are invoked in accordance with the dynamic type of the object used in the call. Non-virtual member functions are invoked in accordance with the static type of the object used in the call.

Function foo is not virtual. That means that it is always called in accordance with static type of the object. The static type in this case is B (since the declared type of the result of B::operator -> is B *), so B::foo is called.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜