2009-02-06 110 views
67

能够超载这将是非常有用的。运算符在C++中,并返回一个对象的引用。为什么你不能重载'。'运算符在C++中?

可以重载operator->operator*但不operator.

是否有技术原因?

+4

您能举一个例子说明何时需要重写'。'。运营商? – 2009-02-06 12:01:15

+4

通常,用例是“智能参考”。一种代理。 – ddaa 2009-02-06 12:12:57

+2

@Gamecat:通读[this](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf)提议增加重载`operator.`的能力和`operator。*`,它有几个例子。 – Mankarse 2012-02-12 02:46:43

回答

51

this quote from Bjarne Stroustrup

操作。 (点)原则上可以使用与 - >相同的技术来过载。但是,这样做会导致问题 有关操作是否适用于对象重载。或一个 对象所指的。例如:

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? 
} 

此问题可以通过多种方式解决。在标准化的时候,哪种方式最好不明显。有关详细信息,请参见The Design and Evolution of C++

27

斯特劳斯has an answer for this question

操作。 (点)原则上可以使用与用于 - >的 相同的技术来重载 。但是,如果这样做,则 会导致有关 操作是否适用于对象 重载的问题。或者是由 所引用的对象。例如:

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

47

Stroustrup说C++应该是一种可扩展但不可变的语言。

点(属性访问)操作符被认为太靠近语言的核心以允许超载。

请参阅The Design and Evolution of C++,第242页,第部分11.5.2智能参考文献

当我决定让运营商->超载,我自然考虑是否操作.也同样可以过载。

当时,我认为以下论点是决定性的:如果obj是类对象,那么obj.m对该对象类的每个成员m都有含义。我们尽量不要通过重新定义内置操作来使语言变为可变(尽管该规则违反了=的急迫需求,并且对于一元的&)。

如果我们允许一类X.超载,我们将无法通过正常手段获得的X成员;我们将不得不使用指针并且->,但是->&也可能已被重新定义。我想要一种可扩展的语言,而不是一个可变的语言。

这些论点很重要,但不是确凿的。特别是在1990年,Jim Adcock提出允许运营商.恰好超载运营商->的方式。

此引用中的“I”是Bjarne Stroustrup。你不可能比那更具权威性。

如果你想真正理解C++(例如“为什么是这样”),你应该阅读本书。

1

这很容易理解,如果你通过运算符函数调用的内部机制, 说一个类复合体可以有两个成员r为实部和i为虚部。 说复杂的C1(10,20),C2(10,2) //我们假设在类中已经有了一个两个参数的构造函数。 现在,如果您编写C1 + C2作为语句,那么编译器会尝试在复数上查找+运算符的重载版本。现在我们假设我是过载+运算符,所以 C1 + C2内部翻译为c1.operator +(c2) 现在假设您的时间可以重载'。'运营商。 所以现在想下面再打电话C1.disp() //显示一个复杂对象的内容现在尝试表示为内部表示 C1.operator。(------),创建完全混乱的东西。这就是我们不能超载的原因。''运算符