重载成员访问运算符->,.* [英] Overloading member access operators ->, .*

查看:113
本文介绍了重载成员访问运算符->,.*的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了成员访问运算符->.*->*等之外,我了解大多数运算符重载.

特别是,什么传递给这些运算符,应该返回什么?

操作员函数(例如operator->(...))如何知道引用了哪个成员?能知道吗它甚至需要知道吗?

最后,是否需要考虑任何常量注意事项?例如,当重载operator[]之类的东西时,通常将需要const版本和非const版本.成员访问运算符是否需要const和非const版本?

解决方案

->

这是唯一真正棘手的问题.它必须是一个非静态成员函数,并且不包含任何参数.返回值用于执行成员查找.

如果返回值是类类型的另一个对象,而不是指针,则随后的成员查找也由operator->函数处理.这称为向下钻取行为".该语言将operator->调用链接在一起,直到最后一个返回指针为止.

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}

->*

这是一个棘手的问题,因为它没有什么特别之处. 非重载版本的左侧需要一个指向类类型的指针的对象,而右侧则需要一个指向成员类型的指针的对象.但是,当您重载它时,您可以接受您喜欢的任何参数并返回您想要的任何东西.它甚至不必是非静态成员.

换句话说,这只是一个普通的二进制运算符,例如+-/.另请参见:自由运算符-> *是否会重载邪恶?

.*.

这些不能重载.当左侧为类类型时,已经具有内置含义.能够在左侧为指针定义它们可能会有点道理,但是语言设计委员会认为这将变得更加混乱而不是有用.

重载->->*..*仅可填充表达式未定义的情况,它永远不会更改在不重载的情况下有效的表达式的含义. /p>

I understand most operator overloading, with the exception of the member access operators ->, .*, ->* etc.

In particular, what is passed to these operator functions, and what should be returned?

How does the operator function (e.g. operator->(...) ) know what member is being refered to? Can it know? Does it even need to know?

Finally, are there any const considerations that need to be taken into account? For example, when overloading something like operator[], generally you will need both a const and non-const version. Do member access operators require const and non-const versions?

解决方案

->

This is the only really tricky one. It must be a nonstatic member function, and it takes no arguments. The return value is used to perform the member lookup.

If the return value is another object of class type, not a pointer, then the subsequent member lookup is also handled by an operator-> function. This is called the "drill-down behavior." The language chains together the operator-> calls until the last one returns a pointer.

struct client
    { int a; };

struct proxy {
    client *target;
    client *operator->() const
        { return target; }
};

struct proxy2 {
    proxy *target;
    proxy &operator->() const
        { return * target; }
};

void f() {
    client x = { 3 };
    proxy y = { & x };
    proxy2 z = { & y };

    std::cout << x.a << y->a << z->a; // print "333"
}

->*

This one is only tricky in that there is nothing special about it. The non-overloaded version requires an object of pointer to class type on the left-hand side and an object of pointer to member type on the right. But when you overload it, you can take any arguments you like and return anything you want. It doesn't even have to be a nonstatic member.

In other words, this one is just a normal binary operator like +, -, and /. See also: Are free operator->* overloads evil?

.* and .

These cannot be overloaded. There is already a built-in meaning when the left-hand side is of class type. Perhaps it would make a little sense to be able to define them for a pointer on the left-hand side, but the language design committee decided that would be more confusing than useful.

Overloading ->, ->*, ., and .* can only fill in cases where an expression would be undefined, it can never change the meaning of an expression that would be valid with no overloading.

这篇关于重载成员访问运算符->,.*的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆