c++中为什么有不能重载的运算符(摘录)

大部分的操作符是可以被重载的,例外的只有“.”、“::”、“?:”和“sizeof”。没有什么非禁止operator?:重载的理由,只不过没有必要而已。另外,expr1?expr2:expr3的重载函数无法保证expr2和expr3中只有一个被执行。
而“sizeof”无法被重载是因为不少内部操作,比如指针加法,都依赖于它,例如:

X a[10];
X* p = &a[3];
X* q = &a[3];
p++; // p points to a[4]
// thus the integer value of p must be
// sizeof(X) larger than the integer value of q


这样,sizeof(X)无法在不违背基本语言规则的前提下表达什么新的语义。
在N::m中,N和m都不是表达式,它们只是编译器“认识”的名字,“::”执行的实际操作是编译时的名字域解析,并没有表达式的运算牵涉在内。或许有人会觉得重载一个“x::y”(其中x是实际对象,而非名字域或类名)是一个好主意,但这样做引入了新的语法[译注:重载的本意是让操作符可以有新的语义,而不是更改语法——否则会引起混乱],我可不认为新语法带来的复杂性会给我们什么好处。

原则上来说,“.”运算符是可以被重载的,就像“->”一样。不过,这会带来语义的混淆——我们到底是想和“.”后面的对象打交道呢,还是“.”后面的东东所实际指向的实体打交道呢?看看这个例子(它假设“.”重载是可以的):

class Y {
public:
void f();
// ...
};

class X { // assume that you can overload . public:
Y* p;
Y& operator.() { return *p; }
void f();
// ...
};

void g(X& x)
{
x.f(); // X::f or Y::f or error?
}
 

在 < <Thinking in C++>>中这样写道:
在可用的运算符集合里存在一些不能重载的运算符。这样限制的通常原因是出于对安全的考虑:如果这些运算符也可以被重载的话,将会造成危害或破坏安全机制,使得事情变得困难或混淆现有的习惯。
现在,成员选择运算符‘.’在类中对任何成员都有一定的意义。但如果允许它重载,就不能用普通的方法访问成员,只能用指针和指针运算符->访问。
成员指针逆向引用的运算符‘.* ’因为与运算符‘.’同样的原因而不能重载。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值