fre*_*low 6 c++ history language-design reference operator-overloading
根据Bjarne Stroustrup的说法,引用了C++以支持运算符重载:
引用的引用主要是为了支持运算符重载.
C按值传递每个函数参数,并且按值传递对象的效率低或不合适,用户可以传递指针.在使用运算符重载的情况下,此策略不起作用.在这种情况下,符号方便是必不可少的,因为如果对象很大,则不能期望用户插入地址运算符.例如:
Run Code Online (Sandbox Code Playgroud)a = b - c;
是可接受的(即常规的)符号,但是
Run Code Online (Sandbox Code Playgroud)a = &b - &c;
不是.无论如何,
&b - &c
在C中已经有了意义,我不想改变它.
在语言中使用指针和引用是C++新手混淆的常见原因.
Bjarne不能通过引入一种特殊的语言规则来解决这个问题,如果存在需要这样的指针的用户定义的运算符函数,它允许对象参数衰减成指针吗?
减法的声明和用法将如下所示:
Foo operator-(const Foo* x, const Foo* y);
a = b - c;
Run Code Online (Sandbox Code Playgroud)
有没有提出/考虑过这样的解决方案?它有任何严重的缺点吗?
是的我知道,由于它们的限制,引用提供了其他优点,但这不是重点.
有趣的是,带有类的C的赋值运算符似乎完全相同:
通过声明一个名为的成员函数来更改类[...]对象的赋值含义
operator=
.例如:Run Code Online (Sandbox Code Playgroud)class x { public: int a; class y * p; void operator = (class x *); };
IME,自动转换是C++的祸根.让我们写一些感谢的电子邮件给Bjarne Stroustrup,因为它没有添加从对象到指针的广泛自动转换.
如果你寻找一个技术原因:在C++中,指针的减法,甚至指向用户定义类型的指针,已经很好地定义了.此外,这会导致每个副本获取对象的重载版操作符的含糊不清.
我不明白这是如何解决这个问题的:operator-
调用指针已经有了意义.
你要定义一个operator-
for Foo*
参数,但那已经存在了.
然后你需要一些人为的语义,"当用指针显式调用时,调用指针算术运算符.当用对象左值调用时,它们会衰减为指针,然后调用重载版本".说实话,这似乎更加人为,而且不仅仅是添加引用.
然后在里面operator-
,我把参数作为指针,然后我最好确保取消引用那些,如果我需要从那里调用另一个(或相同的)运算符.否则我不小心最终会执行指针算术.
您提出的隐式转换与自己进行转换的语义不同.那是:
Foo foo;
bar(foo);
Run Code Online (Sandbox Code Playgroud)
执行从Foo
to 的隐式转换Foo*
,然后调用带有签名的函数void bar(Foo*)
.
但是这段代码会做一些完全不同的事情:
Foo foo;
bar(&foo);
Run Code Online (Sandbox Code Playgroud)
这将也转换为一个Foo*
,并且它还将要求与签名的功能void bar(Foo*)
,但它可能会是一个不同的功能.(operator-
例如,一个是用户重载的运算符,另一个是标准指针算术运算符.
然后考虑模板代码.通常,隐式转换会使模板非常痛苦,因为传入的类型可能不是您要操作的类型.
当然,还有更多的实际问题:
引用启用指针无法实现的优化.(编译器可以假设它们永远不会为空,并且可能更好地进行别名分析)
而且,如果找不到匹配,代码将无声地失败operator-
.而是告诉我的是,编译器会隐式地开始做指针算术.不是一个交易破坏者,但我真的更喜欢在可能的情况下及早发现错误.
C++的目标之一是使其具有通用性:避免使用"魔术"类型或功能.在现实世界的C++中,运算符只是具有不同语法的函数.有了这个规则,它们也会有不同的语义.(如果使用函数语法调用运算符怎么operator+(a, b)
办?
归档时间: |
|
查看次数: |
2044 次 |
最近记录: |