Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > приоритет перегруженных операторов |
Автор: nerdy_weirdie 29.3.2011, 04:15 | ||
Столкнулся с очень странным поведением компилятора VS2005. Вместо того чтобы использовать подходящий оператор присваивания, он вызывает оператор приведения к другому типу, и затем вызывает перегруженный оператор присваивания. Почему он так делает, и как этого избегать. Решение всегда явно задавать тип при вызове оператора присваивания не подходит потому что слишком не надежное - кода много и где-нибудь обязательно да забудется. Надо чтобы компилятор сам выбирал нужный оператор.
Казалось бы, будет вызван оператор CSock& operator = (CSock& p_sockFrom); и всё будет работать как надо, но почему-то в этой строке возвращенный объект сначала преобразуется к типу SOCKET при помощи operator SOCKET (); и затем для присвоения вызывается CSock& operator = (SOCKET p_sockFrom);. В итоге логика учета референсов не работает. Как научить его ходить в лоток? |
Автор: borisbn 29.3.2011, 06:46 |
Не решение, а так... костылёк... А что если в описании класса поднять "правильный" оператор присваивания вверх, перед "неправильными"? |
Автор: Earnest 29.3.2011, 07:26 |
Лучше убрать нафик оператор приведения. Это вообще штука опасная, чревата всякими непредсказуемыми поведениями, особенно для активно развивающегося кода. Лучше замени его явной функцией. И, скорее всего, это константная функция должна быть. Кроме того, хороший тон требует, чтобы оператор присваивания получал константные ссылку, а не копию и уж тем более не просто ссылку. |
Автор: bsa 29.3.2011, 10:32 | ||
nerdy_weirdie, функция FindSocket() возвращает так называемое rvalue, т.е. временный объект. По стандарту С++, нельзя такие объекты передавать в качестве параметров функциям, принимающим объекты по неконстантной ссылке. Так как у тебя есть оператор преобразования (что вообще считается дурным тоном, так как может вызывать подобные проблемы) и оператор присваивания принимающий SOCKET, то компилятор их и использует. По хорошему, достаточно сделать конструктор от (const SOCKET&), чтобы при присваивании объекта типа SOCKET вызвался он, а затем operator=(const CSock&) для полученного объекта:
|
Автор: nerdy_weirdie 29.3.2011, 17:25 |
Спасибо, с константной ссылкой работает. Но всё равно такое поведение мне кажется неадекватным. |
Автор: borisbn 29.3.2011, 17:52 | ||
я правильно понял, что поведение компилятора по стандарту кажется неадекватным ![]() ![]() Бедная M$. Делает не по стандарту (кстати, довольно часто) - ругают. Делают по стандарту - получите, распишитесь ![]() оффтопиковый ![]() а что ты хотел от класса СНосок ? ![]() |
Автор: kemiisto 29.3.2011, 17:59 | ||
По-моему, у ТС сомнения в адыкватности стандарта. То есть в адыкватности языка. Сомнения правильные. ![]() |
Автор: borisbn 29.3.2011, 21:27 |
поехали. Апперкот - компилятор Си++ есть на все известные платформы (кроме разве что андроида) 1 : 0 |
Автор: kemiisto 29.3.2011, 21:30 | ||
Казалось бы, и причём тут адыкватность? ![]() |