| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Вопрос на собеседовании |
| Автор: Paspartu 21.9.2008, 13:54 | ||
| Доброго времени суток. Вот такой вопрос: 23. Что будет напечатано в результате?
Ответ: c) classB classA Как правильно обосновать ответ? пробую так: т.к. функция msg () является виртуальной в базовом классе A и она переопределена в производном классе B, унаследованном от класса A, то решение о том, какая ее версия будет вызвана определяется по типу объекта… т.к. указатель на базовый класс можно использовать для ссылки на объекты любых других классов, выведенных из базового то A * pointer = new B, var – указывает на объект класса B, соответственно pointer->msg() приведет к вызову версии msg () для класса B. При вызове f(*pointer) в функции void f(A cl) будет времмено создан объект класса A и соответственно class.msg() приведет к вызову msg () для класса A. Что Вы думаете по этому поводу? |
| Автор: vinter 21.9.2008, 14:36 |
многабукафф. в первом случае будет выведен classB, по принципу полиморфности. Во втором classA т.к обьект передаеться по значению, значит он будет обрезан до родителя |
| Автор: Mayk 21.9.2008, 15:43 |
compile time error в строчке Добавлено через 26 секунд даже подсветка хворума показывает что этот код крив. |
| Автор: mes 21.9.2008, 17:49 |
по смыслу название переменной "class" тоже неправильно: как параметр передается объект, а не класс... ;) |
| Автор: Paspartu 21.9.2008, 20:46 |
| с class я конечно загнул, аш самому смешно в попыхах писал, код кривой, но важна суть... с принципом полиморфности согласен, а чем обосновать ответ < Во втором classA т.к обьект передаеться по значению, значит он будет обрезан до родителя >? Стандарт? |
| Автор: vinter 21.9.2008, 21:15 |
стандарт я не читал ниразу |
| Автор: Paspartu 21.9.2008, 21:28 |
| Так, понятно, огромное спасибо! Вот еще вопрос дано: char* str = "12345"; и усе! перевернуть все символы не используя буфер т.е. получить я так понял указатель на "54321", по google - л, но хочется понять принцип, и как зная только лишь указатель это можно сделать? |
| Автор: MAKCim 21.9.2008, 21:42 |
| Paspartu, никак в такой формулировке |
| Автор: Paspartu 21.9.2008, 21:47 |
| Вот и я голову ломаю, с массивом все понятно, а так через указатель? В любом случае нужен буфер, хотя в задании четко прописано - дополнительный буфер не использовать!? Во засада! |
| Автор: vinter 21.9.2008, 21:48 | ||
Paspartu, при такой записи вероятно, что нельзя будет сделать, т.к очень часто это воспринимается компилятором как const char* |
| Автор: Rpahut 21.9.2008, 23:52 | ||||
|
| Автор: J0ker 22.9.2008, 03:29 | ||
стандарт тут не при чем данный эффект называется slicing происходит это из-за того, что стандартные конструкторы - в том числе и копиконструктор - не могут быть виртуальными. Т.о. для создания временного объекта вызывается копиконструктор целевого класса |
| Автор: J0ker 22.9.2008, 03:51 | ||||||
как написал vinter это либо не будет компилиться, либо приведет к undefined behavior т.к. по стандарту строковые литералы - константы (2.3.14) |
| Автор: Rickert 22.9.2008, 04:08 | ||
С указателем никак, а если через буффер, то ещё можно так:
|
| Автор: J0ker 22.9.2008, 04:29 | ||||||
|
| Автор: Rickert 22.9.2008, 05:01 |
| Кто больше? |
| Автор: J0ker 22.9.2008, 05:07 | ||
нет у кого длиннее |
| Автор: Torsten 22.9.2008, 12:24 | ||
хм ... в каком то из недавних номеров журнала хакер (летнем) КК показыавл как это сделать. Но реально непонятному кому это нужно, если коде используются такие нестадартные механизмы - я не завидую тому кто будет такой код разбирать и дописывать. Хотя бы потому что это задача легко решается если проходить от конца строки к началу - всего лишь алгоритм. |
| Автор: UnrealMan 22.9.2008, 13:04 | ||||
Тут undefined behavior. |
| Автор: J0ker 22.9.2008, 17:58 | ||||||
в каком месте? |
| Автор: UnrealMan 23.9.2008, 14:08 |
| Между двумя соседними точками следования нельзя дважды модифицировать один и тот же скалярный объект. |
| Автор: J0ker 23.9.2008, 18:13 | ||||
здесь нет соседних точек:
так что всё тип-топ |
| Автор: UnrealMan 24.9.2008, 01:31 | ||||||||||||
Ну, тут-то их конечно нет, т.к. такая программа некорректна Что касается предыдущего твоего примера, то там две соседние точки следования обязательно будут. Первая точка следования будет либо такой:
либо такой:
Следующая точка следования будет согласно абзацу 1.9/16. Функция, о которой идёт речь при упоминании случая с 1.9/17, - это та, что содержит expression-statement, коим является твой кусок кода.
То есть хреново |
| Автор: J0ker 24.9.2008, 05:08 |
| изучаю вопрос |
| Автор: J0ker 24.9.2008, 07:09 | ||
| да, согласен, был неправ (5/4) плюсик вам
программа корректна - эквивалентность некорректна - прояснилось из 5/2 Однако хочу уточнить - согласно тому-же 5/2 - при перегруженном операторе ^= undefined behavior исчезает. Я правильно понимаю? UPD упс, не могу поставить плюсик. Обязательно поставлю когда наберу 100 постов |
| Автор: vinter 24.9.2008, 08:50 | ||
поставил |
| Автор: UnrealMan 24.9.2008, 12:46 | ||||
Напомню, что в теме речь шла про массивы char-ов, а с char-ами такая бодяга не пройдёт.
Перегрузка оператора заключается в определении функции с именем operator operator, где хотя бы один параметр (явный или неявный) имеет пользовательский тип или тип, представляющий собой ссылку на пользовательский тип. На такую функцию, как и на все другие, распространяется правило
|
| Автор: J0ker 24.9.2008, 16:24 | ||
именно это и ввело меня в заблуждение - считал операторы простых типов полностью эквивалентными по реализации операторам классов (за исключением операторов || и &&). Естественно я понимаю что .operator op к простым типам не применим синтаксически. спасибо |
| Автор: Maka6er 24.9.2008, 18:57 | ||
И я нас... сделаю свой вклад
|
| Автор: Annihilator 24.9.2008, 19:54 | ||||
а где память под start выделяешь??? Без буфера - никак
а про strrev(char* s) все дружно забыли. Но опять же без буфера никуда |
| Автор: mes 24.9.2008, 21:03 | ||
посмотрите внимательнее код - память для start не нужна - он используется как указатель на основную строку, равноправный указателю str, под который тоже память нигде не выделялась ) а технология используется следующая :
как видете ни одного стороннего байта не используются. Такое возможно благодаря некоторому свойству оператора XOR. |
| Автор: vinter 24.9.2008, 21:15 |
| ну это все равно не рабочий вариант, считай у нас дано const char * |
| Автор: mes 24.9.2008, 21:37 | ||
ну const char* вобще повернуть нельзя , хоть с буфером хоть без. Можно только получить "повернутую" копию. Так что, ИMXO, в задании просто опечатка. |
| Автор: Maka6er 25.9.2008, 12:23 | ||
А разве обязательно под указатель выделять память? Указатель должен указывать на область в памяти. Я устанавливаю один указатель на начало строки, один - на конец.
const char * - это указатель на строковую константу (строковый литерал), а константу изменить нельзя. |
| Автор: W4FhLF 25.9.2008, 13:02 | ||
А vinter что имел ввиду? |
| Автор: Maka6er 25.9.2008, 13:38 |
Сори, туплю. Я имел ввиду из задания: char* str = "12345"; |
| Автор: serg76 26.9.2008, 13:24 | ||
даже не выделяя переменную для цикла зы полный бред имхо тож самое что бутерброды делать топором |
| Автор: J0ker 26.9.2008, 17:48 | ||||
ты бы почитал сначала обсуждение этот код в большинстве случаев приведет к Segmentation fault и Access violation |
| Автор: serg76 27.9.2008, 10:49 | ||||||
а где приведет то, конкретнее? зы насчет const наскока помню в С через указатели можно все менять для примера к коду выше заменить
на
|
| Автор: mes 27.9.2008, 11:54 | ||
При таком подходе Вы надеетесь, что даные размещенные по указателю str1, размещаются в пользовательской области с правом записи. Однако строчка : говорит компилятору о возможности размещении данных в памяти только для чтения. Как видите результат выполнения операций в таком случае потенциально опасен и зависит от компилятора и его настроек. |
| Автор: J0ker 27.9.2008, 19:04 | ||||||||||
здесь:
строковые литералы явяются константами и могут размещаться в защищенном от записи сегменте возможность присвоения их не константам - тяжелое наследие прошлого Добавлено @ 19:07 объявление типа
размещает массив на стеке - что позволяет менять его содержимое Добавлено @ 19:17
это говорит компилятору, что str константный массив. Но размещение его будет на стеке (потому, что это массив - он просто с инициализатором) выражение:
говорит о том, что str указатель на константную строку, инициализируемый АДРЕСОМ строкового литерала, который возможно находится в защищенном от записи сегменте как грится "почувствуйте разницу" |
| Автор: W4FhLF 28.9.2008, 06:25 | ||
Ну это смотря где его объявить. |
| Автор: J0ker 28.9.2008, 06:55 | ||||
да в функции иначе в секции .rdata (защищенные от записи и исполнения инициализированные данные) и .data (защищенные от исполнения инициализированные данные) соответственно хотя рояля это и не играет |