Почему вы не можете перегрузить '.' оператор в C ++? - PullRequest
75 голосов
/ 06 февраля 2009

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

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

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

Ответы [ 4 ]

61 голосов
/ 06 февраля 2009

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

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

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

51 голосов
/ 06 февраля 2009

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

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

См. Дизайн и развитие C ++ , стр. 242, раздел 11.5.2 Смарт-ссылки .

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

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

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

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

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

Если вы хотите по-настоящему понять C ++ (например, «почему так»), вам обязательно следует прочитать эту книгу.

29 голосов
/ 06 февраля 2009

Страуструп имеет ответ на этот вопрос :

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

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 .

1 голос
/ 26 августа 2015

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...