例如下面的代码:
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 |
|
PHP中文网2017-04-17 13:33:21
Because the associativity of operators is different, dereference operator (Isn’t the format of this code similar to the leading operator? Similar to
std::string operator*(){//...}
, isn’t it exactly*ptr
? But the overloaded->
operator is used like this. Why?ptr->
) is right associative, while member access operator (*
and .
) is left associative. This is an example of different associativity of different symbols. In C++, when the symbols are the same, there will also be examples of different usages resulting in different associativity. For example: ->
1 2 3 4 5 6 7 8 |
|
, etc.), the operator is often a binary operator. For + - * / ()
, lhs op rhs
or lhs.operator op(rhs)
will be called. We Just overload the operator according to this function signature. operator op(lhs, rhs)
or ++
), for --
(left combination) and lhs op
(right combination), we have to find a way to distinguish different usages, So there will be function parameters for placeholders (op rhs
): int
call lhs op
lhs.operator op(int)
call op rhs
rhs.operator op()
), for ->
, there is no need for placeholder function parameters, and it can be directly written as a right-associative function signature, that is, lhs op
call lhs op
lhs.operator op()
andThis is specified by the C++ standard. Forreturns a pointer, why can we directly access class members later, [for example,
std::string* operator->()
]?ptr->size()
, the operator ptr->mem
is interpreted differently depending on the type of ptr
: ->
is a built-in pointer type, it is equivalent to ptr
(*ptr).mem
is a class, it is equivalent to ptr
ptr.operator->()->mem
it will recurse into: ptr->mem
1 |
|
is unary, while operator ->
is binary. Operator .
ultimately accesses members through operator ->
, and .
operator is not allowed to be overloaded and can only be implemented by the compiler. .
defined by the subject: StrPtr
1 2 3 4 5 6 7 8 |
|
The last digression, C++ variable names should not start with an underscore. Starting with an underscore is reserved for the compiler. You can use m_somemember
or somemember_
as a private member name.
天蓬老师2017-04-17 13:33:21
The standard stipulates that the way is written has nothing to do with the type of return value being a pointer.
And the magic is that if what is returned is not a pointer but a class object that overloads the arrow operator, then the arrow operator of the class object will be called until an arrow operator returns a raw Pointer, then retrieve the content of the pointer and perform member access. This process can be infinitely nested and recursed layer by layer. If the compiler searches layer by layer and does not find an arrow operator that returns a raw pointer, it will report an error. For example, if it returns a class object that does not have an overloaded arrow operator, or a value such as int.
If you follow the general operator overloading logic, then the arrow operator should return a reference, and there seems to be no problem logically. But if the above situation occurs, I'm afraid there will be something like
-> -> ... ->
. I think this is probably one of the reasons.
I hope to communicate with people who have different understandings.
怪我咯2017-04-17 13:33:21
The standard stipulates that ->either calls -> that returns an object, returns a pointer, or reports an error.