>,。*(C ++)
我理解大多数运算符重载,除了成员访问运算符->
, .*
, ->*
等
特别是,传递给这些运算符函数的是什么,以及应该返回什么?
操作员的功能如何(例如, 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"
}
->*
这只是一个棘手的问题,没有什么特别之处。 非重载版本需要一个指向左侧类类型指针的对象和右侧指向成员类型的指针对象。 但是当你重载它时,你可以接受任何你喜欢的参数并返回你想要的任何东西。 它甚至不必是非静态成员。
换句话说,这个只是一个普通的二元运算符,比如+
, -
和/
。 另见:免费运营商 - > *重载邪恶?
.*
和.
这些不能超载。 当左边是类类型时,已经有了一个内置的含义。 也许能够将它们定义为左侧的指针会有点意义,但是语言设计委员会认为这会比有用的更困惑。
超载->
, ->*
, .
, .*
只能填充表达式未定义的情况,它永远不会改变表达式的含义,而且不会超载。
您不能超载成员访问权限.
(即什么->
的第二部分)。 但是,您可以重载一元解引用操作符*
(即第一部分是什么->
)。
C ++ ->
运算符基本上是两个步骤的联合,如果您认为x->y
等同于(*x).y
,则这很清楚。 当x
是你的类的一个实例时,C ++允许你定制如何处理(*x)
部分。
->
重载的语义有点奇怪,因为C ++允许你返回一个常规的指针(它将被用来查找指向的对象),或者如果这个类还提供了一个->
操作符,它将返回另一个类的实例。 在第二种情况下,从这个新实例继续搜索解除引用的对象。
运算符 - >是特殊的。
“它有额外的非典型约束:它必须返回一个也有一个指针解引用操作符的对象(或对象的引用),或者它必须返回一个指针,该指针可用于选择指针解除引用操作符箭头指向的内容。 “ 布鲁斯埃克尔:思考CPP第一卷:操作员 - >
提供额外的功能是为了方便,所以你不必打电话
a->->func();
你可以简单地做:
a->func();
这使得运算符 - >与其他运算符重载不同。
链接地址: http://www.djcxy.com/p/72907.html上一篇: >, .* (C++)
下一篇: Reducing code duplication between operator= and the copy constructor