80

能够重载 . C++ 中的运算符并返回对对象的引用。

你可以超载operator->operator*但不能operator.

这有技术原因吗?

4

4 回答 4

62

请参阅Bjarne Stroustrup 的这句话

操作员 。(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++ 的设计和演变

于 2009-02-06T12:07:03.480 回答
52

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

点(属性访问)操作符被认为太接近语言的核心而不允许重载。

请参阅C++ 的设计和演变,第 242 页,第11.5.2 节智能参考

当我决定允许 operator 重载时->,我自然会考虑 operator.是否可以类似地重载。

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

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

这些论点是有分量的,但不是结论性的。特别是在 1990 年,Jim Adcock 提议允许 operator的重载与 operator. 完全->一样。

这句话中的“我”是 Bjarne Stroustrup。你不能比这更有权威。

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

于 2009-02-06T12:09:55.703 回答
28

Stroustrup 对这个问题有一个答案

操作员 。(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

于 2009-02-06T12:07:03.090 回答
1

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

于 2015-08-26T09:25:22.660 回答