Почему вы не можете перегрузить '. оператор в C++?


было бы очень полезно иметь возможность перегружать . оператор в C++ и возвращает ссылку на объект.

можно перегрузить operator-> и operator* а не operator.

есть ли техническая причина для этого?

4 68

4 ответа:

посмотреть Это цитата из Бьярне Страуструпа:

оператора . (точка) в принципе может быть перегружена с использованием того же техника, используемая для ->. Однако это может привести к вопросам о том, предназначена ли операция для перегрузки объекта . или объект, на который ссылается . Например:

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++.

Страуструп сказал, что C++ должен быть расширяемым, но не изменяемым языком.

оператор dot (attribute access) рассматривался как слишком близкий к ядру языка, чтобы позволить перегрузку.

посмотреть дизайн и эволюция C++, страница 242, раздел 11.5.2 Умных Ссылок.

когда я решил разрешить перегрузку оператора ->, Я, естественно, считается ли оператор . может быть точно так же перегружены.

в то время я считал следующие аргументы убедительными: если obj - это объект класса obj.m имеет значение для каждого члена m класса этого объекта. Мы стараемся не делать язык изменчивым, переопределяя встроенные операции (хотя это правило нарушается для = из крайней необходимости, и для унарных &).

если мы допустили перегрузку . класс X, мы не сможем получить доступ к членам X обычными средствами, мы должны использовать указатель и ->, а -> и & возможно, также были переопределены. Мне нужен был расширяемый язык, а не изменяемый.

эти аргументы весомы, но не окончательны. В частности, в 1990 году Джим Адкок предложил разрешить перегрузку оператора .ровно как оператор -> есть.

"я" в этой цитате-Бьярне Страуструп. Вы не можете быть больше авторитетнее, чем это.

если вы хотите действительно понять C++ (как в "почему это так"), вы должны обязательно прочитать эту книгу.

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

эта проблема может быть решена в несколько пути. На момент стандартизации, было не очевидно, в какую сторону пойдет быть лучший. Дополнительные сведения см. В разделе D&E.

Это очень легко понять, если вы идете через внутренний механизм функция вызова оператора, Скажем, комплекс класса может иметь два члена r для действительной части и i для мнимой части. Скажи Комплекс C1(10,20),C2 (10,2) // мы предполагаем, что в классе уже есть конструктор с двумя аргументами. Теперь, если вы пишете C1+C2 в качестве оператора компилятор пытается найти перегруженную версию оператора + на комплексное число. Теперь предположим, что я перегружаю + оператор, так C1+C2 внутренне переводится как c1.оператор+(С2) Теперь предположим, что на время существ вы можете перегрузить '.' оператор. так что теперь думайте после вызова C1.disp () / / отображение содержимого сложного объекта теперь попробуйте представить как внутреннее представление C1.оператор.(------), совершенно грязные вещи созданы. Вот почему мы не можем перегружать". оператор