为什么你不能重载 '.' C++中的运算符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/520035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't you overload the '.' operator in C++?
提问by Ferruccio
It would be very useful to be able to overload the . operator in C++ and return a reference to an object.
能够重载 . C++ 中的运算符并返回对对象的引用。
You can overload operator->
and operator*
but not operator.
你可以超载operator->
,operator*
但不能operator.
Is there a technical reason for this?
这有技术原因吗?
采纳答案by Anton Gogolev
See this quote from Bjarne Stroustrup:
Operator . (dot) could in principle be overloaded using the same technique as used for ->. However, doing so can lead to questions about whether an operation is meant for the object overloading . or an object referred to by . For example:
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
This problem can be solved in several ways. At the time of standardization, it was not obvious which way would be best. For more details, see The Design and Evolution of C++.
操作员 。(dot) 原则上可以使用与 -> 相同的技术重载。但是,这样做可能会导致有关操作是否针对对象重载的问题。或引用的对象。例如:
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
这个问题可以通过多种方式解决。在标准化的时候,哪种方式最好并不明显。有关更多详细信息,请参阅C++ 的设计和演变。
回答by ddaa
Stroustrup said C++ should be an extensible, but not mutable language.
Stroustrup 说 C++ 应该是一种可扩展但不可变的语言。
The dot (attribute access) operator was seen as too close to the core of the language to allow overloading.
点(属性访问)运算符被视为过于接近语言的核心而不允许重载。
See The Design and Evolution of C++, page 242, section 11.5.2 Smart References.
请参阅C++ 的设计和演变,第 242 页,第11.5.2节智能参考。
When I decided to allow overloading of operator
->
, I naturally considered whether operator.
could be similarly overloaded.At the time, I considered the following arguments conclusive: If
obj
is a class object thenobj.m
has a meaning for every memberm
of that object's class. We try not to make the language mutable by redefining built-in operations (though that rule is violated for=
out of dire need, and for unary&
).If we allowed overloading of
.
for a classX
, we would be unable to access members ofX
by normal means; we would have to use a pointer and->
, but->
and&
might also have been re-defined. I wanted an extensible language, not a mutable one.These arguments are weighty, but not conclusive. In particular, in 1990 Jim Adcock proposed to allow overloading of operator
.
exactlythe way operator->
is.
当我决定允许 operator 重载时
->
,我自然会考虑 operator.
是否可以类似地重载。当时,我认为以下论点是决定性的:如果
obj
是类对象,则对该对象类的obj.m
每个成员都具有意义m
。我们尽量不通过重新定义内置操作来使语言可变(尽管由于=
迫切需要和一元而违反了该规则&
)。如果我们允许
.
一个类的重载X
,我们将无法X
通过正常方式访问的成员;我们将不得不使用指针 and->
,但->
and&
也可能已被重新定义。我想要一种可扩展的语言,而不是可变的。这些论点是有分量的,但不是决定性的。特别是,在 1990 年,Jim Adcock 提议允许操作符
.
完全按照操作符的方式重载->
。
The "I" in this quote is Bjarne Stroustrup. You cannot be more authoritative than that.
这句话中的“我”是 Bjarne Stroustrup。你没有比这更权威的了。
If you want to really understand C++ (as in "why is it this way"), you should absolutely read this book.
如果你想真正理解 C++(如“为什么这样”),你绝对应该阅读这本书。
回答by mfazekas
Stroustrup has an answer for this question:
Stroustrup 对这个问题有一个答案:
Operator . (dot) could in principle be overloaded using the same technique as used for ->. However, doing so can lead to questions about whether an operation is meant for the object overloading . or an object referred to by . For example:
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
This problem can be solved in several ways. At the time of standardization, it was not obvious which way would be best. For more details, see D&E.
操作员 。(dot) 原则上可以使用与 -> 相同的技术重载。但是,这样做可能会导致有关操作是否针对对象重载的问题。或引用的对象。例如:
class Y { public: void f(); // ... }; class X { // assume that you can overload . Y* p; Y& operator.() { return *p; } void f(); // ... }; void g(X& x) { x.f(); // X::f or Y::f or error? }
这个问题可以通过多种方式解决。在标准化的时候,哪种方式最好并不明显。有关更多详细信息,请参阅D&E。
回答by Sourav Ghosh
It is very easy to understand, if you go through the internal mechanism of operator function invocation, Say a class complex can have two member r for real part and i for imaginary part. Say Complex C1(10,20),C2(10,2)// we assume there is an already a two argument constructor within class. Now if you write C1+C2as a statement then compiler try to find the overloaded version of + operator on complex number. Now we assume that I overload + operator, so C1+C2internally translated as c1.operator+(c2)Now assume for the time beings you can overload '.' operator. so now think following call C1.disp()//display content of a complex object Now try to represent as an internal representation C1.operator.(------), completely messy things created. That is the reason why we can't overload '.' operator
很容易理解,如果你通过操作符函数调用的内部机制,假设一个类复合体可以有两个成员 r 表示实部,i 表示虚部。说Complex C1(10,20),C2(10,2)// 我们假设类中已经有一个双参数构造函数。现在,如果您将C1+C2编写为语句,那么编译器会尝试在复数上找到 + 运算符的重载版本。现在我们假设我重载了 + 运算符,所以 C1+C2 在内部被翻译为c1.operator+(c2)现在假设暂时你可以重载 '.' 操作员。所以现在考虑以下调用C1.disp()//显示复杂对象的内容 现在尝试表示为内部表示 C1.operator.(------),创建了完全凌乱的东西。这就是我们不能重载 '.' 的原因。操作员