Какие операторы нельзя перегружать в C++?
Неперегружаемые операторы C++
Ответы (7)
Из Википедии:
Operator Name Syntax
Bind pointer to member by reference a.*b
Member a.b
Scope resolution a::b
Size of sizeof(a)
Ternary a ? b : c
Type identification typeid(a)
Я почти уверен, что C++ FAQ Lite, вероятно, охватывает это. Сразу могу вспомнить тернарный оператор, оператор .
и оператор разрешения области видимости (::
). Подумав немного, поскольку оператор .
не может быть перегружен, .*
, вероятно, тоже не может быть перегружен.
Есть также некоторые операторы, которые можно, но почти никогда не следует перегружать, включая оператор запятой, &&
, ||
, каждый из которых обычно создает точку последовательности. &&
и ||
также только (обычно) оценивают правильный операнд, если это необходимо. Ни одна из этих характеристик не относится к перегруженному оператору.
Хотя для этого есть несколько причин, перегрузка унарного оператора &
(адрес-оф) также часто является довольно плохой идеей. Адрес объекта в значительной степени приравнивается к его идентификатору, поэтому его перегрузка может сделать несколько других вещей относительно сложными.
Изменить: что касается оценки правильного операнда только в случае необходимости (он же «Оценка короткого замыкания»): рассмотрите что-то вроде x && y
. Выражение может быть истинным только в том случае, если левый операнд истинен. Если левый операнд оценивается как false
, то выражение также должно быть ложным, а C (и C++) гарантирует, что правый операнд не вообще будет оцениваться. Это удобно (например), если вы хотите сделать что-то вроде if (ptr != NULL && ptr->member /*...*/ )
. В этом случае, если указатель в NULL, выполнение останавливается, и вы никогда не пытаетесь разыменовать указатель.
Та же основная идея верна и для ||
, но наоборот. В этом случае, если левый операнд оценивается как true
, то выражение в целом должно быть true
, независимо от того, что будет оцениваться правым операндом, поэтому (опять же) C и C++ гарантируют, что в этом случае правый операнд не будет оценивается.
Однако при перегрузке этих операторов при вычислении выражения all всегда будут оцениваться оба операнда. Первое выражение попытается разыменовать указатель, даже если это нулевой указатель, поэтому поведение будет неопределенным.
?:
в первом абзаце, но остальные заставили меня проголосовать за вас.
- person Gorpik; 20.05.2010
?:
- тернарный оператор, поэтому он включен, просто под другим именем...
- person Jerry Coffin; 20.05.2010
&
, а не унарный. OTOH, Boost::Assign действительно перегружает оператор запятой и заставляет его работать довольно разумно (в этом отношении я сделал то же самое, хотя и не так хорошо). Я не могу точно вспомнить, но Boost::Spirit, вероятно, перегружает пару, против которой я рекомендовал.
- person Jerry Coffin; 20.05.2010
operator()()
может работать так же хорошо, как запятая с некоторым прокси-объектом в миксе.
- person Matthieu M.; 20.05.2010
Object* p = /**/; if (p && p->isValid())
. Если бы &&
оценивал 2 термина (левый и правый), то мы бы использовали нулевой указатель для вызова isValid
, что привело бы к неопределенному поведению. Однако если вы перегружаете этот оператор, то при выборе перегруженного оператора будут оцениваться оба термина, что изменит семантику, которую он традиционно несет.
- person Matthieu M.; 20.05.2010
Из этой статьи о перегрузке операторов
Большинство может быть перегружено. Единственные операторы C, которые не могут быть . и ?: (и sizeof, который технически является оператором). C++ добавляет несколько собственных операторов, большинство из которых можно перегрузить, за исключением :: и .*.
so
.
?:
::
.*
.
, .*
, ?:
, ::
, sizeof
и typeid
. (из http://en.wikipedia.org/wiki/C%2B%2B_operators#Other_operators)
Следующие операторы не могут быть перегружены в C++:
. example: object.member_function()
.* example: object_reference.*member_function_ptr();
:: example: some_name_space::function()
?: example: z = y > z ? y : z (ternary operator)
GIYF: http://www.google.com/search?q=What+operators+can+not+be+overloaded+in+c%2B%2B%3F
Первый результат:
http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.5
Большинство может быть перегружено. Единственные операторы C, которые не могут быть . и ?: (и sizeof, который технически является оператором). C++ добавляет несколько собственных операторов, большинство из которых можно перегрузить, за исключением :: и .*.
Операторы .
, :?
, ::
, .*
, typeid
и sizeof
.