Було б дуже корисно мати можливість перевантажити. в C ++ і повертає посилання на об'єкт.
Ви можете перевантажити operator->
і , operator*
але неoperator.
Чи є для цього технічна причина?
Було б дуже корисно мати можливість перевантажити. в C ++ і повертає посилання на об'єкт.
Ви можете перевантажити operator->
і , operator*
але неoperator.
Чи є для цього технічна причина?
.
дозволені, тому, можливо, якийсь розумний, але жахливий динамічний диспетчерський хак, який дозволяє висловити крапковий продукт як matrix1 . matrix2
.
Відповіді:
Дивіться цю цитату Бьярна Струструпа :
Оператор. (крапка) в принципі може бути перевантажена за допомогою тієї ж техніки, що і для ->. Однак це може призвести до питань про те, чи призначена операція для перевантаження об'єкта. або об'єкт, на який посилається. Наприклад:
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 ++ .
operator .
operator.
явної паралелі з operator->
. І як ви могли зробити перевантаження дозволу?
Строструп сказав, що C ++ повинен бути розширюваною, але не мінливою мовою.
Оператор точки (доступ до атрибута) вважався занадто близьким до ядра мови, щоб дозволити перевантаження.
Див . Дизайн та еволюція 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.operator + (c2) Тепер припустимо, що для істот часу ви можете перевантажити '.' оператора. так що тепер подумайте про наступний виклик C1.disp () // відображати вміст складного об’єкта. Тепер спробуйте представити як внутрішнє представлення C1.operator. (------) , створені абсолютно безладні речі. Ось чому ми не можемо перевантажити ''. оператора
operator.