Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Вопросы для интервью


Автор: azesmcar 11.11.2008, 06:55
Довольно часто сталкиваешся на форумах с вопросами типа "какие вопросы задают при приеме на работу?"
Я предлагаю создать раздел где мы совместными усилиями будем выкладывать вопросы которые задаем или задавали нам во время интервью. Многим хочеться проверить свои знания в области C++ и для них данный раздел будем весьма полезен. Если администрация поддержит идею можно закрепить ее и даже открыть подобные темы во всех разделах посвященных языкам программирования.

Спасибо за внимание

Автор: azesmcar 11.11.2008, 07:18
С моей стороны пока пара вопросов которые люблю задавать во время интервью

1. Написать код на С++, который выяснит и выведет в консоль "Да" если в некоем А классе есть виртуальные функции и соответственно "Нет" - если их там нет
2. Написать код на С++, который выяснит и выведет в консоль "Да" если некая переменная определенного типа константна и "Не"т соответственно если не константна.

теперь немного code review

Код

void f(int* p)
{
   p = new int[2];
   p[0] = 1;
   p[1] = 0;
}

int main()
{
   int* p = 0;
   f( p );
   std::cout << p[0] << std::endl;
   delete p;
}

Какие проблемы есть в данном коде?

Вопрос из Саттера
Код

some_function( std::auto_ptr<A>( new A), std::auto_ptr<A>( new A ) );

Какие потенцианьные проблемы есть в данном коде?

можно заменить на
Код

int i = 0;
some_function( i++, i++ );

Какие потенцианьные проблемы есть в данном коде?

для особо наглых (добавлю - кого хочеться завалить) ;)
Вопрос из Саттера
Код

for (int i = 0; i < 10; ++i)
{
   //ТОДО????/
   total += i;
}

Какие проблемы есть в данном коде?

далее вопросы
1. dynamic_cast, static_cast, reinterpret_cast, const_cast
2. Исключения из конструкторов и деструкторов
3. Разница между тернарным оператором и if - else
4. Перегрузка и значения по умолчанию в виртуальных функциях
5. Оператор new, перегрузка, placement new и явный вызов деструктора
6. Немного о шаблонах, typename и.т.д..
7. Очередность обработки catch блоков по очереди или по подходящему типу (если сперва поймать базовый тип, дойдет ли дело до остальных)
8. Design patterns

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

Автор: Rickert 11.11.2008, 08:21
azesmcar, а ответы? smile 

Автор: azesmcar 11.11.2008, 08:41
А я думал людям интересно будет самим попробовать smile
Ладно..ответы

---------------------------------------------------------------------------------------------------------------
Цитата

1. Написать код на С++, который выяснит и выведет в консоль "Да" если в некоем А классе есть виртуальные функции и соответственно "Нет" - если их там нет

Код

class B : public A
{
public:
   virtual ~A() {};
};

int main()
{
       std::cout << ( sizeof(A) == sizeof(B) ) ? "Yes!" : "No :(" << std::endl;
}

---------------------------------------------------------------------------------------------------------------
Цитата

2. Написать код на С++, который выяснит и выведет в консоль "Да" если некая переменная определенного типа константна и "Не"т соответственно если не константна.


Код

template <class T>
bool is_const(const T& v)
{
   return true;
}

template <class T>
bool is_const( T& v)
{
   return false;
}

int main()
{
    const int a = 3;
    std::cout << is_const( a ) ? "const" : "non const" << std::endl;
}

---------------------------------------------------------------------------------------------------------------
Код

void f(int* p)
{
   p = new int[2];
   p[0] = 1;
   p[1] = 0;
}
int main()
{
   int* p = 0;
   f( p );
   std::cout << p[0] << std::endl;
   delete p;
}


ответ
при вызове функции указатель не передаеться по ссылке а копируется, в следствии в функции main указатель не будет инициализирован. Ну и удалять массивы нужно так delete [] p. И вообще рекомендуется проводить очистку памяти в том же модуле где и выделение.
---------------------------------------------------------------------------------------------------------------
Код

some_function( std::auto_ptr<A>( new A), std::auto_ptr<A>( new A ) );


ответ
постановка аргументов функции по стандарту не определено, т.е. по стандарту вполне приемлемо выполнение вызова функции в следующей поочередности
1. new A
2. new A
3. Вызов конструктора для std::auto_ptr
4. Вызов второго конструктора для std::auto_ptr

в результате если конструктор А сгенерирует исключение при втором вызове - получиться утечка памяти smile извращение не правда ли?
---------------------------------------------------------------------------------------------------------------
Код

for (int i = 0; i < 10; ++i)
{
   //????/ТОДО
   total += i;
}

ответ
Ну а тут вообще извращение smile все писать не буду, напишу только что "??/" заменяется на "\" что означает пропустить следующий <enter>, а в данном контексте просто следующая строка будет закоментарена. Кому интересно подробнее
http://en.wikipedia.org/wiki/C_trigraph

Автор: Alek86 11.11.2008, 10:56
azesmcar, первый ответ не стандартен. Класс, содержащий вирт функции не обязан иметь указатель на таблицу. И класс, не содержащий вирт функции, не обязан НЕ иметь этот указатель.

помойму, это реализовнао в бусте, причем ОЧЕНЬ сложно

а вопрос о триграфах в интервью - это еще большее извращение
их никто не знает и знать не хочет
и спрашивать о них поступающих на работу - только если хош завалить

тогда уж лучше спрашивай, существуют ли ссылки на функции, ссылки на функции члены и т.п.

Автор: Ln78 11.11.2008, 11:10
Цитата(Alek86 @  11.11.2008,  10:56 Найти цитируемый пост)
azesmcar, первый ответ не стандартен.


Alek86, ИМХО, этот вопрос и бессмысленен, разве что для того, чтобы найти причину не взять сотрудника. Трудно представить себе реальную ситуацию, когда такой способ может использоваться. Индусский код по определению истинности переменной и то изящнее. 
К тому же в ответе почему-то virtual ~A(), в классе B smile 

Автор: azesmcar 11.11.2008, 11:10
Цитата

а вопрос о триграфах в интервью - это еще большее извращение


а я что сказал? для особо наглых которых хочешь завалить, кстати не соглашусь, я знаю, и хочу знать еще больше. Если есть какие-то узкие аспекты, я непременно хочу о них знать, несмотря на то буду использовать или нет, знания не повредят.

а насчет первого - знаю что не стандартен, тут не вопрос стандарта, я сообщаю человеку что решение не должно быть обьязательно стандартным, тут вопрос как человек думает..просто на размышление. Виртуальная таблица тоже не входит в стандарт, но ее почти всегда спрашивает в виде формулировки "как реализован полиморфизм во многих компиляторах". Можно навести человека на ответ и тем самым понять насколько он глубоко представляет себе язык и вообще програмирование, и как он думает.

Автор: Alek86 11.11.2008, 11:10
и насчет второго
Код

int main()
{
    enum {E1};
    is_const( E1 ) ? "const" : "non const";
}

 smile

Добавлено через 56 секунд
аа, хорошо
я просто сказал - вдруг ты не знал smile

Автор: azesmcar 11.11.2008, 11:13
Цитата

Alek86, ИМХО, этот вопрос и бессмысленен, разве что для того, чтобы найти причину не взять сотрудника. Трудно представить себе реальную ситуацию, когда такой способ может использоваться. Индусский код по определению истинности переменной и то изящнее. 
К тому же в ответе почему-то virtual ~A(), в классе B smile  


Спорный вопрос мне кажеться. если задается вопрос - не значит что при неправильном ответе или отсутствии такового сотрудник на работу принят не будет.
Чем больше он знает - тем лучше. Если он подумает и ответит - несмотря на то что ответ не стандартен разве вы не повысите о нем свое мнение? А если не ответит не факт что снизите. Насчет деструктора - не компилировал, писал прямо здесь..щас исправлю

Добавлено через 2 минуты и 55 секунд
Цитата

и насчет второго

int main()
{
    enum {E1};
    is_const( E1 ) ? "const" : "non const";
}



и что? ошибка компиляции и ничего страшного, вообще то речь шла только о переменных smile Я многим второй вопрос вообще только для интегера задавал, мало кто решал. smile)

Автор: Alek86 11.11.2008, 11:17
Ln78, не знаю, как насчет "есть ли вирт функции", но насчет "есть ли вирт конструктор" - это даже в бусте есть

http://www.boost.org/doc/libs/1_37_0/libs/type_traits/doc/html/boost_typetraits/reference/has_virtual_destructor.html


к примеру, dynamic_cast для неполиморфных типов не работает

Автор: Ln78 11.11.2008, 11:19
azesmcar, если бы вопрос был задан примерно так: а каким образом обычно реализуется полиморфизм, то это было бы ясно и без затей. А так: приведи ситуацию, когда я вывожу потомка класса, наверное, знаю определение его и всех базовых классов для него, но вот таким образом буду проверять нахождение виртуальных функций. Разве что у этого класса 777 предков, но в реальной жизни как-то я бы поостерёгся использовать такой метод.

Автор: Alek86 11.11.2008, 11:20
azesmcar, сори
хреново я прочел твой топик, видимо smile

Автор: Mayk 11.11.2008, 11:25
Цитата(azesmcar @  11.11.2008,  12:41 Найти цитируемый пост)
{
   //????/ТОДО
   total += i;
}





ответ
Ну а тут вообще извращение  все писать не буду, напишу только что "??/" заменяется на "\" что означает пропустить следующий <enter>, а в данном контексте просто следующая строка будет закоментарена. Кому интересно подробнее
http://en.wikipedia.org/wiki/C_trigraph

Нет. \ означает пропустить следующий ентер тогда и только тогда когда он стоит в конце строки.
в данном случае это не так.

Автор: azesmcar 11.11.2008, 11:26
Цитата

azesmcar, если бы вопрос был задан примерно так: а каким образом обычно реализуется полиморфизм, то это было бы ясно и без затей. А так: приведи ситуацию, когда я вывожу потомка класса, наверное, знаю определение его и всех базовых классов для него, но вот таким образом буду проверять нахождение виртуальных функций. Разве что у этого класса 777 предков, но в реальной жизни как-то я бы поостерёгся использовать такой метод.


разумеется! smile никто и не говорит о реальной жизни, вопрос только на обдумывание и никто не говорит что надо использовать метод. Если надо узнать полиморфен класс или нет то лучший способ конечно как сказал Alek86 - dynamic_cast потому что [Саттер] (предпочитайте ошибки времени компиляции - ошибкам времени выполнения) smile

Mayk, сорри smile верное замечание
исправляюсь
Код

{
   //ТОДО????/
   total += i;
}


С кем не бывает ? smile

Автор: Alek86 11.11.2008, 11:34
немного подправлю - я привел далеко не способ определения, а вариант, где может понадобиться знание полиморфности
способ определения тут
http://www.boost.org/doc/libs/1_37_0/libs/type_traits/doc/html/boost_typetraits/reference/is_polymorphic.html
в код лучше не заглядывать без хорошей подготовки и крепких нервов smile

Автор: azesmcar 11.11.2008, 11:53
Alek86, а где код? не можешь ссылку кинуть?

Автор: Alek86 11.11.2008, 12:54
azesmcar, скачай буст, там он и есть
http://www.boost.org/users/download/

кстати, если у вас используется STL (по нему вопросы должны быть обязательно), то буст вам скорее всего очень пригодится

Автор: azesmcar 11.11.2008, 12:58
Alek86, используеться конечно smile
но буст - пока не вошел в стандарт из принципа не использую. Нет никаких гарантий что синтаксис функций или классов не изменится со временем не так ли?
буст я смотрел, очень полезная штука но использовать пока не хочу.

Добавлено через 3 минуты и 3 секунды
Цитата

кстати, если у вас используется STL (по нему вопросы должны быть обязательно)

есть конечно smile
1. Типы итераторов
2. Типы контейнеров
3. Распределение в памяти для всех типов контейнеров..дополнительные расходы
4. Сложность поиска для всех контейнеров

Кстати, вроде тема для того чтобы народ делился smile почему все молчат? Какие вопросы вы задаете?

Автор: Alek86 11.11.2008, 13:06
Цитата(azesmcar @  11.11.2008,  12:58 Найти цитируемый пост)
Нет никаких гарантий что синтаксис функций или классов не изменится со временем не так ли?

если ты не подвержен децкому "хочу все поновее", то бояться особо нечего. можно просто не обновляться.
+ буст разрабатывается серьезными ребятами (чуть ли не комитетом по стандарту плюсов) - потому интерфейс его меняется крайне редко.

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

Автор: azesmcar 11.11.2008, 13:16
Alek86
Цитата

если ты не подвержен децкому "хочу все поновее", то бояться особо нечего. можно просто не обновляться.


не подвержен smile мне старье милее
Цитата

+ буст разрабатывается серьезными ребятами (чуть ли не комитетом по стандарту плюсов) - потому интерфейс его меняется крайне редко.

знаю, но в том-то и дело что "крайне редко", но меняеться. Даже для такой функции как clear() стандарт не говорит что завтра в нее не добавят новых параметров со значениями по умолчанию, и серьезные ребята подстраховываются smile
Дело конечно спорное и вероятность изменения интерфейса не так уж велика, но тут дело скорее в другом..в принципе smile

Логические вопросы есть конечно, но этот раздел посвящен С++, потому решил умолчать об этом

Автор: Rickert 11.11.2008, 13:48
Не знаю что о человеке может сообщить ответ на первый вопрос, поясните smile 

Автор: Mayk 11.11.2008, 13:49
Цитата(Alek86 @  11.11.2008,  17:06 Найти цитируемый пост)
по теме - мне кажется надо задать вопросы по основам плюсов, ООП и (главное) логическую задачку. нужно ведь понять, насколько умный человек перед тобой сидит, а не насколько начитанный.

Тогда логическая задачка должна быть придуманной самостоятельно. Иначе это будет что-то типа "а читал ли человек о трех лампочках"

Автор: azesmcar 11.11.2008, 14:17
Цитата

Не знаю что о человеке может сообщить ответ на первый вопрос, поясните


поясняю smile
Если ответил
Представляет как устроен полиморфизм, что такое виртуальная таблица, знает что для класса храниться указатель на виртуальную таблицу. Умеет применять теоретические знания для решения практических задач - это не однозначно конечно, но вместе с остальными тестами дает кое какое представление

Если не ответил
Само по себе практически ничего не означает так как мог просто не додуматься, и возможно в другой раз ответил бы..со всеми бывает. Но с остальными задачами дает кое какое представление.

Это не из тех задач после нерешения которых интервью прекращается smile

Автор: Alek86 11.11.2008, 15:43
Цитата(Mayk @  11.11.2008,  13:49 Найти цитируемый пост)
Тогда логическая задачка должна быть придуманной самостоятельно.

как у Спольски - без решения.
Чтоб посмотреть, как он будет выкручиваться smile

Автор: Ln78 11.11.2008, 16:59
Цитата(azesmcar @  11.11.2008,  14:17 Найти цитируемый пост)
Если ответил
Представляет как устроен полиморфизм, что такое виртуальная таблица, знает что для класса храниться указатель на виртуальную таблицу.


azesmcar, я бы такое решение не стал писать. Наверное, я бы спросил, что имеется в виду как раз это дело с размерами, если бы и писал, то что-то используя шаблоны, под конкретный класс как-то уж очень экзотическое решение. Для меня в данном конкретном случае большим показателем было бы употребление правильной терминологии: "виртуальная таблица" - это что-то полумифическое (хотя не исключено, что просто жаргон, нужно уточнить дополнительно), а вот "таблица виртуальных функций" - чётко показывает, что никакой мистики в реализации полиморфизма нет, можно сделать её простым и понятным способом.  smile 

Автор: JackYF 11.11.2008, 17:37
azesmcar, я бы на первый вопрос ответил, что implementation defined, поэтому задача стандартного решения не имеет smile
Впрочем, тут уже выяснили.

С триграфами я тоже никогда не хотел и не хочу связываться.

Автор: SABROG 11.11.2008, 19:17
Триграфы пришли к нам из языка Си и компилятор gcc вроде как их просто игнорит. Т.ч. тут нет правильного и однозначного ответа.

Автор: J0ker 11.11.2008, 21:37
Цитата(azesmcar @  11.11.2008,  12:58 Найти цитируемый пост)
Кстати, вроде тема для того чтобы народ делился smile почему все молчат? 

понтоваться наверное не хотят  smile 

Автор: vinter 12.11.2008, 12:33
Цитата(azesmcar @  11.11.2008,  08:18 Найти цитируемый пост)
Исключения из конструкторов и деструкторов

и что ты тут хочешь услыщать? свою точку зрения, или тебе действительно интересно, что по этому поводу думает кандидат?

Цитата(azesmcar @  11.11.2008,  08:18 Найти цитируемый пост)
Разница между тернарным оператором и if - else

а она есть?

Цитата(azesmcar @  11.11.2008,  08:18 Найти цитируемый пост)
Оператор new, перегрузка, placement new и явный вызов деструктора

ппц, а если человеку ниразу не надо было перегружать new? это смотрится в гугле за 3 минуты, а исключая начинку этот оператор не отличается от других, так какой смысл от этого вопроса?

Цитата(Mayk @  11.11.2008,  14:49 Найти цитируемый пост)
Тогда логическая задачка должна быть придуманной самостоятельно. Иначе это будет что-то типа "а читал ли человек о трех лампочках"

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

Автор: mes 12.11.2008, 12:59
Цитата(vinter @  12.11.2008,  12:33 Найти цитируемый пост)

а она есть?

вот вам два условных примера, попробуйте реализовать через if  smile 
Код

struct A1 { A1(int a) {/*...*/} };
struct A2 : public A1 { A2(bool flag) : A1(flag ? 100  : 0) {} };

Код

const bool  a = (sizeof (A1)==sizeof (A2))? true :false;

Автор: vinter 12.11.2008, 13:32
Цитата(mes @  12.11.2008,  13:59 Найти цитируемый пост)
вот вам два условных примера, попробуйте реализовать через if  

точно smile

Автор: Vyacheslav 12.11.2008, 14:05
Цитата(azesmcar @  11.11.2008,  14:17 Найти цитируемый пост)
поясняю smile
Если ответил
Представляет как устроен полиморфизм, что такое виртуальная таблица, знает что для класса храниться указатель на виртуальную таблицу. Умеет применять теоретические знания для решения практических задач - это не однозначно конечно, но вместе с остальными тестами дает кое какое представление

Угу. Только вот стандарт не предполагает обязательного использование виртуальных таблиц. И таблицы виртуальных функций - это лишь одна из реализаций полиморфизма, довольно успешная и поэтому получившая распространение. Если не ошибаюсь, в некоторых  первых компиляторах встречались другие способы реализации, о которых успешно забыли. И если у меня кандидат пытается объяснить суть полиморфизма посредством таблиц, я его сразу прерываю и предлагаю ограничиваться в объяснении  формулировками  ООП и объемом  стандарта С++  При этом, что очень странно, довольно часто сразу же возникают затруднения. Меня довольно часто привлекают к проведению технических интервью, и с моей точки зрения Ваши вопросы выглядят больше как способ продемонстрировать Вашу эрудицию, нежели выяснить действительную квалификацию кандидата. 
И настораживает фраза, что у Вас есть вопросы для засыпки особо наглых. То есть Вы выполняя техническое интервью, берете на себя не свойственные задачи: рубите квалифицированного специалиста из-за собственных предпочтений. Ваша - это всего лишь выяснить компетентность кандидата по весьма узкому техническому  вопросу.  Вопросы о  психической адекватности обычно решается другими людьми, в частности специалистами отдела HR. 
Любопытно, были ли в Вашей практике отзывы : типа "Кандидат показал очень высокий уровень знаний в объеме стандарта С++. Оцениваю его квалификацию, как минимум не ниже моей, а может быть и выше"? Очень сомневаюсь



Автор: Vyacheslav 12.11.2008, 14:41
Цитата(vinter @  12.11.2008,  12:33 Найти цитируемый пост)
Цитата(azesmcar @  11.11.2008,  08:18 Найти цитируемый пост)
Исключения из конструкторов и деструкторов

и что ты тут хочешь услыщать? свою точку зрения, или тебе действительно интересно, что по этому поводу думает кандидат?

Ну этот то вопрос  как раз интересный. И задав его, я бы для начала хотел бы услышать ответы : допустимы, недопустимы. Если недопустимы, то как : компилятор не даст, или невозможно гарантировать безопасность кода. Если компилятор дает, но не гарантирована написание безопасного кода, то попросил бы привести пример.  Если допустимы, то что надо учитывать. И разобравшись, насколько правильно кандидат понимает проблемы, я бы выслушал его личное мнение  по данному вопросу о возможном использовании. И не столь важно, совпадет или не совпадет оно с моим( если не совпадет, то будет совпадать в случае если кандидат попадет в мою команду  smile ), главное, что чтобы отстаивал свою точку зрения аргументировано  

Автор: Mayk 12.11.2008, 15:04
Цитата(vinter @  12.11.2008,  16:33 Найти цитируемый пост)
 он редко пытается размышлять вслух, а это как раз и самое интересное. 

Вот это кстати верно.

Цитата(mes @  12.11.2008,  16:59 Найти цитируемый пост)
вот вам два условных примера, попробуйте реализовать через if

реализовать можно. правда надо учитывать что if - это statement а не expression.
Код

struct A1 { A1(int a) {/*...*/} };

struct A2 : public A1 { 
    A2(bool flag) : A1(calcA(flag)) {} 
    static int calcA(bool flag) {
        if(flag) return 100; 
                                  return 0;
    }
};

template<class A, class B>
bool equalSizes(){
    if(sizeof(A) ==sizeof(B))
        return 1;
    return 0;
}

int foo()
{
    const bool  a = equalSizes<A1,A2>();
}

Цитата(azesmcar @  11.11.2008,  15:10 Найти цитируемый пост)
как реализован полиморфизм во многих компиляторах". 

Тут наверное ожидается; "Полиморфизм времени выполнения или времени компиляции?"

Автор: Torsten 12.11.2008, 16:36
Почитав эту тему, и еще похожие и сам проходя интервью пришел к выводу, что во всех интервью обычно задают 50% вопросов, ответы на которые есть у Саттера...
Собственно идя на интервью рекомендую прочитать обе его книги + про шаблоны что-нибудь, типа Гаммы, Всиледеса или Александреску (хотя этот черт пишет сложно, раза по 2-3 перечитывать приходится чтобы некоторые вещи понять).

Автор: Vyacheslav 12.11.2008, 18:11
Цитата(Torsten @  12.11.2008,  16:36 Найти цитируемый пост)
Почитав эту тему, и еще похожие и сам проходя интервью пришел к выводу, что во всех интервью обычно задают 50% вопросов, ответы на которые есть у Саттера...

Ну не знаю. Вам просто не повезло. Когда я проходил и когда проводил сам, все обычно ограничивалось объемом книги Страструпа первого  издания с поправками на стандарт. Проблема в том, что даже в этом объеме у меня из 10 кандидатов хороший отзыв получали не больше двух.  Иногда шел и думал, что судя по резюме интервью будет чисто формальным для человека с таким-то опытом работы.
А начинаешь спрашивать, получаешь ответы типа:
- виртуальные функции можно переопределять в производных классах, в отличие невиртуальных.
- в случае неудачи выделения памяти, глобальный new возвращает NULL

Просто при проведении интервью надо четко понимать, что твоя задача не завалить кандидата убийственным  вопросом, а выяснить в какой степени он знает С++ именно для повседневной работы над проектом в команде.



Автор: Alek86 12.11.2008, 18:44
Цитата(Vyacheslav @  12.11.2008,  18:11 Найти цитируемый пост)
виртуальные функции можно переопределять в производных классах, в отличие невиртуальных.

есть переопределение, а есть перегрузка. и вроде как переопределение - это только для виртуальных, чтоб работал полиморфизм

хотя могу и ошибаться в названиях
да и все равно, имхо, так придираться к терминологии - не правильно


Цитата(Vyacheslav @  12.11.2008,  18:11 Найти цитируемый пост)
глобальный new возвращает NULL

в студии есть волшебный дефайн - кидать исключение или возвращать NULL

Автор: J0ker 12.11.2008, 18:56
Цитата(Alek86 @  12.11.2008,  18:44 Найти цитируемый пост)
в студии есть волшебный дефайн - кидать исключение или возвращать NULL 

Цитата(Vyacheslav @  12.11.2008,  18:11 Найти цитируемый пост)
- в случае неудачи выделения памяти, глобальный new возвращает NULL

вы не поверите, но это правда, и это никакой не дефайн
new(std::nothrow) T;
 smile 


Автор: mes 12.11.2008, 19:06
Цитата(Vyacheslav @  12.11.2008,  18:11 Найти цитируемый пост)
- виртуальные функции можно переопределять в производных классах, в отличие невиртуальных.

а чем не устраивает такой ответ ?

Цитата(Alek86 @  12.11.2008,  18:44 Найти цитируемый пост)
есть переопределение, а есть перегрузка. и вроде как переопределение - это только для виртуальных, чтоб работал полиморфизм

 И я, и я и я того же мнения (© из м/ф Винни Пух и все-все-все)

Автор: J0ker 12.11.2008, 19:13
Цитата(Alek86 @  12.11.2008,  18:44 Найти цитируемый пост)
есть переопределение, а есть перегрузка. и вроде как переопределение - это только для виртуальных, чтоб работал полиморфизм

переопределение (overriding) - это создание в классе потомке функции с той-же сигнатурой, что и в классе предке
перегрузка (overloading) - это создание функций с одним именем но разными наборами параметров в одном неймспейсе

Добавлено через 1 минуту и 28 секунд
Цитата(mes @  12.11.2008,  19:06 Найти цитируемый пост)
а чем не устраивает такой ответ ?

тем, что он неправильный  smile 


Автор: mes 12.11.2008, 19:53
Цитата(J0ker @  12.11.2008,  19:13 Найти цитируемый пост)
переопределение (overriding) - это создание в классе потомке функции с той-же сигнатурой, что и в классе предке

А как называется тогда переопределение реализации функции ?

Автор: Alek86 12.11.2008, 20:02
J0ker, я ж написал - на собеседованиях придираться к терминологии - не правильно
ибо это не экзамен, а проверка знаний

Цитата(J0ker @  12.11.2008,  18:56 Найти цитируемый пост)
вы не поверите, но это правда, и это никакой не дефайн

я говорю не про new(nothrow), а про new
этим дефанойм меняется поведение самого new

Автор: Vyacheslav 12.11.2008, 20:09
Цитата(Alek86 @  12.11.2008,  18:44 Найти цитируемый пост)
есть переопределение, а есть перегрузка. и вроде как переопределение - это только для виртуальных, чтоб работал полиморфизм

хотя могу и ошибаться в названиях
да и все равно, имхо, так придираться к терминологии - не правильно


Ну вот приехали.   smile 
Это не просто терминология, это понимание, что такое полиморфизм и когда нужно и когда ненужно использовать виртуальные функции и деструкторы. Причем я считаю, что этот вопрос просто так типа поддержать разговор. 


Цитата(Alek86 @  12.11.2008,  18:44 Найти цитируемый пост)
в студии есть волшебный дефайн - кидать исключение или возвращать NULL

Я набираю людей оценивая их знание С++. Иногда я понятия не имею, на каком компиляторе они в конечном счете будут выполнять проект. Мне известно только одно: все эти компиляторы как минимум процентов 93-97% соответствуют стандарту. Вот будьте любезны его и знать.

Добавлено @ 20:12


Цитата(mes @  12.11.2008,  19:53 Найти цитируемый пост)
Цитата(J0ker @  12.11.2008,  19:13 Найти цитируемый пост)
переопределение (overriding) - это создание в классе потомке функции с той-же сигнатурой, что и в классе предке

А как называется тогда переопределение реализации функции ?


Так и называется :переопределением  smile 



Автор: Vyacheslav 12.11.2008, 20:35
Цитата(Alek86 @  12.11.2008,  20:02 Найти цитируемый пост)
я говорю не про new(nothrow), а про new
этим дефанойм меняется поведение самого new

Угу. А в проекте у кандидата, допустим, предполагается написание приложения, которое должно компилироваться под Visual C++, gcc и acc соотвественно работать под Window, Linux и HP-UX.  smile

Добавлено через 2 минуты и 42 секунды
Цитата(Alek86 @  12.11.2008,  20:02 Найти цитируемый пост)
J0ker, я ж написал - на собеседованиях придираться к терминологии - не правильно
ибо это не экзамен, а проверка знаний

Именно, и собеседование как раз и выявило значительный пробел в понимании различия виртуальных и не виртуальных функций  smile 

Автор: J0ker 12.11.2008, 20:38
Цитата(mes @ 12.11.2008,  19:53)
Цитата(J0ker @  12.11.2008,  19:13 Найти цитируемый пост)
переопределение (overriding) - это создание в классе потомке функции с той-же сигнатурой, что и в классе предке

А как называется тогда переопределение реализации функции ?

ну если вы функцию определили и порешили использовать, то, пардон, как вы без ее реализации обойдетесь?
обзывания "переопределение" и "перегрузка" относится к сигнатурам - реализация - это следствие

Добавлено через 1 минуту и 56 секунд
Цитата(Alek86 @  12.11.2008,  20:02 Найти цитируемый пост)
J0ker, я ж написал - на собеседованиях придираться к терминологии - не правильно
ибо это не экзамен, а проверка знаний

причем тут терминология
это РАЗНЫЕ вещи имеющие РАЗНЫЕ названия
они НЕ СИНОНИМЫ, их нельзя смешивать и иметь личное мнение по этому поводу  smile 

Автор: Vyacheslav 12.11.2008, 20:45
Цитата

перегрузка (overloading) - это создание функций с одним именем но разными наборами параметров в одном неймспейсе

Ну вот вопрос про overloading .  smile 
В каком случае я могу иметь две функции с одним именем и одинаковым набором парамеметров, но с разным типом возвращаемого результата?
И почему этот случай не противоречит выше процитированному определению? ( последний вопрос задается факультативно   smile )

Добавлено @ 20:48
Цитата(J0ker @  12.11.2008,  18:56 Найти цитируемый пост)
вы не поверите, но это правда, и это никакой не дефайн
new(std::nothrow) T;

Вообще это мой факультативный вопрос, который я задаю при первом правильном ответе на первый вопрос  smile 

Автор: J0ker 12.11.2008, 20:51
Цитата(Vyacheslav @  12.11.2008,  20:45 Найти цитируемый пост)
В каком случае я могу иметь две функции с одним именем и одинаковым набором парамеметров, но с разным типом возвращаемого результата?

тока в одном - если они в разных неймспейсах либо в разных юнитах и имеют внутренний линкейдж - проще говоря, не видят друг друга
тип возвращаемого параметра не входит в сигнатуру

Цитата(Vyacheslav @  12.11.2008,  20:45 Найти цитируемый пост)
И почему этот случай не противоречит выше процитированному определению?

потому, что заданое вами условие не блещет полнотой

Автор: Vyacheslav 12.11.2008, 20:57
Цитата(J0ker @  12.11.2008,  20:51 Найти цитируемый пост)
тока в одном - если они в разных неймспейсах либо в разных юнитах и имеют внутренний линкейдж - проще говоря, не видят друг друга
тип возвращаемого параметра не входит в сигнатуру

Для простоты( хотя это уже подсказка ) это два метода одного класса, имеющие одинаковое название, одинаковый набор ( формально в объявлении  smile  ) параметров, но возвращающие результат разного типа.

Автор: mes 12.11.2008, 21:00
Цитата(Vyacheslav @  12.11.2008,  20:57 Найти цитируемый пост)
Для простоты( хотя это уже подсказка ) это два метода одного класса, имеющие одинаковое название, одинаковый набор ( формально в объявлении  smile  ) параметров, но возвращающие результат разного типа.

кажется я чувствую о чем речь. Когда у  одного из методов прараметр this константный ?
только это точно не коректный вопрос.

Цитата(Vyacheslav @  12.11.2008,  20:45 Найти цитируемый пост)
И почему этот случай не противоречит выше процитированному определению? (

противоречит.

Автор: Alek86 12.11.2008, 21:10
Цитата(Vyacheslav @  12.11.2008,  20:35 Найти цитируемый пост)
Именно, и собеседование как раз и выявило значительный пробел в понимании различия виртуальных и не виртуальных функций   

ну, то уже другой вопрос. я отвечал именно на 
Цитата(Vyacheslav @  12.11.2008,  18:11 Найти цитируемый пост)
виртуальные функции можно переопределять в производных классах, в отличие невиртуальных.

такое может сказать любой опытный программист, которому просто не приходило в голову засесть за зубрежку терминов smile
это, кстати и ответ на  вопрос
Цитата(J0ker @  12.11.2008,  20:38 Найти цитируемый пост)
причем тут терминология



Автор: Vyacheslav 12.11.2008, 21:13
Цитата(mes @  12.11.2008,  21:00 Найти цитируемый пост)
кажется я чувствую о чем речь. Когда у  одного из методов прараметр this константный ?
только это точно не коректный вопрос.

Чем? 
Методы класса map
Код

   iterator find (const key_value&);
   const_iterator find (const key_value&) const;

Кстати на него отвечали относительно легко, а кто читал Страуструпа в первом издании и помнил о первом скрытом параметре отвечали и на второй.
Примерно так бы эти методы выглядели после обработки препроцессором в старинном компиляторе, который назывался  "С with classes" , если на том момент кто-нибудь решил реализовать константность метода  smile 
Код

   iterator find (map *This, const key_value&);
   const_iterator find ( const map* This, const key_value&) ;


Автор: Alek86 12.11.2008, 21:15
Цитата(Vyacheslav @  12.11.2008,  20:57 Найти цитируемый пост)
Для простоты( хотя это уже подсказка ) это два метода одного класса, имеющие одинаковое название, одинаковый набор ( формально в объявлении    ) параметров, но возвращающие результат разного типа.

если ты про шаблоны, то это тоже некорректный вопрос
ибо параметр является частью сигнатуры

Добавлено через 1 минуту и 28 секунд
а, таки про константность... smile

Автор: Vyacheslav 12.11.2008, 21:17
Цитата(Alek86 @  12.11.2008,  21:10 Найти цитируемый пост)
такое может сказать любой опытный программист, которому просто не приходило в голову засесть за зубрежку терминов smile

То есть, если у Вы будете строить иерархию классов, которые не используют полморфизм, но знаете, что в некоторых производных потребуется некоторая модификация их поведения относительно реализации в производном  классе, Вы методы сделаете виртуальными?

Автор: J0ker 12.11.2008, 21:18
Цитата(Vyacheslav @ 12.11.2008,  20:57)
Цитата(J0ker @  12.11.2008,  20:51 Найти цитируемый пост)
тока в одном - если они в разных неймспейсах либо в разных юнитах и имеют внутренний линкейдж - проще говоря, не видят друг друга
тип возвращаемого параметра не входит в сигнатуру

Для простоты( хотя это уже подсказка ) это два метода одного класса, имеющие одинаковое название, одинаковый набор ( формально в объявлении  smile  ) параметров, но возвращающие результат разного типа.

непонял, что это был вопрос  smile 
никак наскока я понимаю

Автор: Alek86 12.11.2008, 21:18
но при этом надо было хорошо выделить, слово формально
ибо опытные люди сразу вместо "имеющие одинаковое название, одинаковый набор параметров" обычно подставляют слово "сигнатура" smile

Добавлено через 1 минуту и 46 секунд
Vyacheslav, а зачем делать иерархию классов без полиморфизма?

без полиморфизма делаются только наследники от вектора (чтобы потом через полгода на эту чудо-"иерархию" материться)

Автор: J0ker 12.11.2008, 21:21
Цитата(Vyacheslav @ 12.11.2008,  21:13)
Цитата(mes @  12.11.2008,  21:00 Найти цитируемый пост)
кажется я чувствую о чем речь. Когда у  одного из методов прараметр this константный ?
только это точно не коректный вопрос.

Чем? 

тем, что скрытый параметр является параметром, а константность параметра - и как следствие объявление метода const - входит в сигнатуру 
такшо можете вычеркнуть сей вопрос - он некоректен

Автор: Alek86 12.11.2008, 21:22
кстати, для этого очень подойдет агрегация, а не наследование
и это, кстати, во всех тех книжках пишется
"если класс НЕ ЯВЛЯЕТСЯ другим классом а только очень похож и меняет некоторое поведение - используйте агрегацию"

Добавлено через 33 секунды
J0ker, там главное слово - ФОРМАЛЬНО smile
я тоже не заметил

Автор: J0ker 12.11.2008, 21:24
Цитата(Alek86 @  12.11.2008,  21:10 Найти цитируемый пост)
Цитата(Vyacheslav @  12.11.2008,  18:11 Найти цитируемый пост)
виртуальные функции можно переопределять в производных классах, в отличие невиртуальных.

такое может сказать любой опытный программист, которому просто не приходило в голову засесть за зубрежку терминов

не может
ибо тут ошибка не в терминологии, а в принципе
невиртуальные функции-члены переопределяются ничем не хуже виртуальных

Автор: Alek86 12.11.2008, 21:26
J0ker, ты не ответил на вопрос - как в терминологии называется переопределение вирт функций? ибо я, к примеру, не знаю. и называю переопределением именно переопределение вирт функций (странно, но меня при этом все понимают smile )

Автор: Vyacheslav 12.11.2008, 21:27
Цитата(Alek86 @  12.11.2008,  21:18 Найти цитируемый пост)
но при этом надо было хорошо выделить, слово формально
ибо опытные люди сразу вместо "имеющие одинаковое название, одинаковый набор параметров" обычно подставляют слово "сигнатура" smile

То есть это Вы не заметили?
Цитата(Vyacheslav @  12.11.2008,  20:57 Найти цитируемый пост)
одинаковый набор ( формально в объявлении  smile  )

И странные у Вас опытные люди: обычные методы не переопределяют, о виртуальных функциях могут мыслить только в терминах наличия-отсутствия таблиц виртуальных функция,  а одинаковый набор параметров сразу же переводят в сигнатуру. Кстати о птичках, формулировку  overloading  в таком виде давал не я. Я ею только воспользовался.  smile

Добавлено через 2 минуты и 45 секунд
Еще вопрос о виртуальных функциях
Можно ли виртуальный деструктор базового класса объявить чистым? 
И если можно, как сделать, чтобы производные от этого не пострадали?


Автор: J0ker 12.11.2008, 21:31
Цитата(Alek86 @  12.11.2008,  21:22 Найти цитируемый пост)
J0ker, там главное слово - ФОРМАЛЬНО

обратите внимание на мой исходный пост - упоминание сигнатуры полностью лишает смысла последующие попытки Vyacheslav завалить интервьюируемого - константность метода входит в сигнатуру, т.к. объявляет скрытый this константным

Добавлено через 1 минуту и 25 секунд
Цитата(Alek86 @ 12.11.2008,  21:26)
J0ker, ты не ответил на вопрос - как в терминологии называется переопределение вирт функций? ибо я, к примеру, не знаю. и называю переопределением именно переопределение вирт функций (странно, но меня при этом все понимают smile )

переопределение и виртуальной, и не виртуальной функции называется переопределением
у них просто разный механизм вызова

Автор: Vyacheslav 12.11.2008, 21:34
Цитата(J0ker @  12.11.2008,  21:21 Найти цитируемый пост)
тем, что скрытый параметр является параметром, а константность параметра - и как следствие объявление метода const - входит в сигнатуру 
такшо можете вычеркнуть сей вопрос - он некоректен 

А я не спорю и полностью соглашусь, если в стандарте Вы найдете понятие сигнатуры. Я не помню, оно там есть?
А если нет, то мой вопрос корректен. То о чем я умолчал в вопросе, являлось ответом на вопрос.
 

Автор: warmonger_ 12.11.2008, 21:34
Цитата(Alek86 @  12.11.2008,  20:26 Найти цитируемый пост)
и называю переопределением именно переопределение вирт функций (странно, но меня при этом все понимают smile ) 

Я бы подумал о замещении не виртуальной функции.

Автор: Vyacheslav 12.11.2008, 21:35
Цитата(J0ker @  12.11.2008,  21:31 Найти цитируемый пост)
переопределение и виртуальной, и не виртуальной функции называется переопределением
у них просто разный механизм вызова


Точно. Но механизм вывода - это реализация. А стандарт описывает только поведение  smile. 

Автор: Alek86 12.11.2008, 21:37
Цитата(Vyacheslav @  12.11.2008,  21:27 Найти цитируемый пост)
То есть это Вы не заметили?

из троих ответивших двое сразу начали говорить о сигнатуре
ибо такой "подлянки" не ожидали smile


а вот насчет чистых деструкторов - хороший вопросик
если чел опытный и не знает формальных названий, он переспросит "а чистый - это без определения или просто с =0?"
имхо, лучше любого ответа smile

Добавлено через 1 минуту и 5 секунд
Цитата(warmonger_ @  12.11.2008,  21:34 Найти цитируемый пост)
Я бы подумал о замещении не виртуальной функции.

а как ты называешь ...эээ... другую реализацию вирт ф-й в наследниках?
мож хоть кто-то ответит, что есть точное название...

Автор: J0ker 12.11.2008, 21:41
Цитата(Vyacheslav @  12.11.2008,  21:27 Найти цитируемый пост)
Можно ли виртуальный деструктор базового класса объявить чистым? 

я чет не понял ты нас интервьюируешь чтоль?  smile

Добавлено через 4 минуты и 8 секунд
Цитата(Vyacheslav @ 12.11.2008,  21:34)
Цитата(J0ker @  12.11.2008,  21:21 Найти цитируемый пост)
тем, что скрытый параметр является параметром, а константность параметра - и как следствие объявление метода const - входит в сигнатуру 
такшо можете вычеркнуть сей вопрос - он некоректен 

А я не спорю и полностью соглашусь, если в стандарте Вы найдете понятие сигнатуры. Я не помню, оно там есть?
А если нет, то мой вопрос корректен. То о чем я умолчал в вопросе, являлось ответом на вопрос.

1.3.10
вычеркивайте

Автор: warmonger_ 12.11.2008, 21:46
Цитата(Alek86 @  12.11.2008,  20:37 Найти цитируемый пост)
а как ты называешь ...эээ... другую реализацию вирт ф-й в наследниках?

"Говорят, что функция из производного класса с тем же именем и с тем же набором типов аргументов, что и виртуальная функция в базовом классе, замещает (override) виртуальную функцию из базового класса" Страуструп

я ошибся.

Автор: J0ker 12.11.2008, 21:48
Цитата(Vyacheslav @  12.11.2008,  21:35 Найти цитируемый пост)
Точно. Но механизм вывода - это реализация. А стандарт описывает только поведение 

вызова
ну как-то сложно представить, что разное поведение можно реализовать одним механизмом вызова, правда?  smile 

Автор: warmonger_ 12.11.2008, 21:48
листаю Страуструпа:
если функция не фиртуально, то тоже замещение. так что я не ошибся)

Автор: J0ker 12.11.2008, 21:50
Цитата(Alek86 @  12.11.2008,  21:37 Найти цитируемый пост)
из троих ответивших двое сразу начали говорить о сигнатуре

сигнатуру я упомянул ДО подлянок - ибо это и есть суть вопроса - линкейдж, нэймспейс и сигнатура

Автор: Vyacheslav 12.11.2008, 21:57

Цитата(J0ker @  12.11.2008,  21:41 Найти цитируемый пост)
1.3.10
вычеркивайте 

уговорили  smile 
Приду домой перечитаю ... и может буду возражать
Потому что я формально прав:
первый вопрос, условие при котором
и второй , почему  не противоречит  smile 
Казуистика, согласен. smile 



Цитата(J0ker @  12.11.2008,  21:41 Найти цитируемый пост)
я чет не понял ты нас интервьюируешь чтоль?

Нет. Просто тема "Вопросы для интервью"
А отвечать или нет  - это уж  как хотите.  

Автор: J0ker 12.11.2008, 22:00
Цитата(Vyacheslav @  12.11.2008,  21:57 Найти цитируемый пост)
Приду домой перечитаю ... и может буду возражать

не будете
"
1.3.10 signature [defns.signature]
the information about a function that participates in overload resolution (13.3): the types of its parameters
and, if the function is a class member, the cv- qualifiers (if any) on the function itself and the class in which
the member function is declared.2) The signature of a function template specialization includes the types of
its template arguments (14.5.5.1).
"

Автор: J0ker 12.11.2008, 22:17
Цитата(Alek86 @  12.11.2008,  21:37 Найти цитируемый пост)
а вот насчет чистых деструкторов - хороший вопросик
если чел опытный и не знает формальных названий, он переспросит "а чистый - это без определения или просто с =0?"
имхо, лучше любого ответа

ну не думаю, что незнание терминологии лучше правильного ответа
так-что отвечайте  smile 

Автор: vinter 12.11.2008, 22:32
Цитата(J0ker @  12.11.2008,  23:17 Найти цитируемый пост)
ну не думаю, что незнание терминологии лучше правильного ответа

терминалогия идет лесом, если она не критична. В данном случае это именно так, вы на работу программиста берете или буквоеда?

Добавлено через 51 секунду
P.S надо две темы6 вопросы и обсуждение вопросов, т.к в потоке ответов будет тяжело выловить нужное.

Автор: Alek86 12.11.2008, 22:48
Цитата(J0ker @  12.11.2008,  22:17 Найти цитируемый пост)
ну не думаю, что незнание терминологии лучше правильного ответатак-что отвечайте

мож я и преувеличил
конечно лучше знать и термины и ответ...
но если испытуемый сыпет умными словами, меня бы это насторожило - возможно предо мною сидит теоретик, взяв которого на работу, рискуешь получить еще одного "идеолога"... smile
конечно это не значит, что он не должен, к примеру, знать слова "интерфейс" smile

Добавлено через 28 секунд
Цитата(vinter @  12.11.2008,  22:32 Найти цитируемый пост)
надо две темы6 вопросы и обсуждение вопросов

поздно :(

Автор: mes 12.11.2008, 23:28
Цитата(Vyacheslav @  12.11.2008,  21:27 Найти цитируемый пост)
Можно ли виртуальный деструктор базового класса объявить чистым? 

объявить можно (не чистым, а абстрактным  smile )
Цитата(Vyacheslav @  12.11.2008,  21:27 Найти цитируемый пост)

И если можно, как сделать, чтобы производные от этого не пострадали?

добавить реализацию .  smile  Нельзя только чтоб "символ чистоты" (=0) и реализация были вместе в объявлении.

Ответный вопрос к  Vyacheslav, является ли нижеупомянутый класс "чисто" абстрактным  и по какой причине ? smile  
Код

class A
{
   public:
      virtual ~A() {}
      virtual  void vf () =0;
      virtual int  f   (int a, int b) { return a+b; }
              int  sum (int a, int b) { return a+b; }
};


Автор: J0ker 13.11.2008, 00:31
Цитата(vinter @  12.11.2008,  22:32 Найти цитируемый пост)
терминалогия идет лесом, если она не критична. В данном случае это именно так, вы на работу программиста берете или буквоеда?

Цитата(Alek86 @  12.11.2008,  22:48 Найти цитируемый пост)
но если испытуемый сыпет умными словами, меня бы это насторожило - возможно предо мною сидит теоретик, взяв которого на работу, рискуешь получить еще одного "идеолога"...

по мне, так ответ в духе "я не понимаю, о чем вы говорите" - приближает соискателя к провалу
при этом, конечно не возбраняется употребление соискателем альтернативных терминов, но только если он сам понимает их значение

Добавлено через 7 минут и 13 секунд
Цитата(mes @  12.11.2008,  23:28 Найти цитируемый пост)
объявить можно (не чистым, а абстрактным

абстрактными бывают классы
а вот чистыми бывают виртуальные функции (pure-virtual)

Цитата(mes @  12.11.2008,  23:28 Найти цитируемый пост)
нижеупомянутый класс "чисто" абстрактным

ну для начала вам надобно ввести определение "чисто" абстрактного класса  smile 

Автор: Vyacheslav 13.11.2008, 02:50
[
Цитата(J0ker @  12.11.2008,  22:00 Найти цитируемый пост)

не будете
"
1.3.10 signature [defns.signature]
the information about a function that participates in overload resolution (13.3): the types of its parameters
and, if the function is a class member, the cv- qualifiers (if any) on the function itself and the class in which
the member function is declared.2) The signature of a function template specialization includes the types of
its template arguments (14.5.5.1).


Буду.  smile Тип скрытого параметра тут формально тут не причем. В сигнатуру непосредственно включается cv-спецификация функции smile.  Каким конкретно образом она включается -это уже детали.
И формально в классе можно иметь не одну функцию с одним именем и одинаковым списком параметров, а четыре smile
типа

 
Код

class A
{
    void func(int);       // signature:               class: A   +  types:int + fucntion qualifiers:
    void func(int) const; // signature:           class: A    +  types:int + fucntion qualifiers:const
    void func(int) volatile; //signature           class: A   +  types:int + fucntion qualifiers:volatile
    void func(int) const volаtile; //signature  class:A   +  types:int  + fucntion qualifiers:const, volatile
};



Так что вопрос вполне корректен 
А вот ответ на второй вышел несколько натянутым. 

Автор: J0ker 13.11.2008, 04:43
Цитата(Vyacheslav @  13.11.2008,  02:50 Найти цитируемый пост)
Буду.  smile Тип скрытого параметра тут формально тут не причем. В сигнатуру непосредственно включается cv-спецификация функции smile.  Каким конкретно образом она включается -это уже детали.
И формально в классе можно иметь не одну функцию с одним именем и одинаковым списком параметров, а четыре smile
типа

Цитата(Vyacheslav @  12.11.2008,  21:34 Найти цитируемый пост)
А я не спорю и полностью соглашусь, если в стандарте Вы найдете понятие сигнатуры. 

я вас чесгря не понимаю

Добавлено через 3 минуты
Цитата(Vyacheslav @  13.11.2008,  02:50 Найти цитируемый пост)
Тип скрытого параметра тут формально тут не причем.

он формально причем - константность метода указывает на константность скрытого параметра - иначе это сделать невозможно, т.к. он скрытый
именно поэтому не бывает константных функций не мемберов - там нечему быть константным

Автор: mes 13.11.2008, 10:23
Цитата(J0ker @  13.11.2008,  04:43 Найти цитируемый пост)

он формально причем - константность метода указывает на константность скрытого параметра - иначе это сделать невозможно, т.к. он скрытый
именно поэтому не бывает константных функций не мемберов - там нечему быть константным 

ага, вот пример для определения к кому относится cоnst:
Код

struct A;

void test (A * a) {}

struct A 
{
    void myfunc () const { test (this); } // если const  относится не к параметру this, а к методу, то этот код должен компилиться.
};

Автор: Alek86 13.11.2008, 12:24
Цитата(mes @  13.11.2008,  10:23 Найти цитируемый пост)
ага, вот пример для определения к кому относится cоnst:

пример показал только константность this
никто не требует именно передавать this в качестве параметра

Автор: vinter 13.11.2008, 12:30
вы уже 3-ю страницу спорите ни о чем smile, нормальный вопрос Вячеслав задал, если к словам не придераться.

Автор: Vyacheslav 13.11.2008, 13:10
Цитата(J0ker @  13.11.2008,  04:43 Найти цитируемый пост)
он формально причем - константность метода указывает на константность скрытого параметра - иначе это сделать невозможно, т.к. он скрытый
именно поэтому не бывает константных функций не мемберов - там нечему быть константным

Немного наоборот. Он  здесь "причем" фактически, формально  - непричем.  В стандарте прописано, что сигнатуру входит cv-квалификаторы. То что они применимы только к методам класса - это тоже требование
По стандарту 8.5.2 описание декларации функции(неважно какой)  следущее 
 D1 ( parameter-declaration-clause ) cv- qualifier(opt)  exception-specifaction(opt)
 
И я пока не нашел упоминание, что для function members в список параметров входит скрытый  параметр( имеется  в виду с точки зрения терминологии стандарта). Это примерно также, как объяснять  поведение виртуальных функций посредством VMT.
Только проблема в том, что стандарт описывает поведение виртуальных функций, а не VMT.  VMT - это всего лишь конкретная реализация, которая выполнена так, что работа  виртуальных функций отвечала требования стандарта, а не наоборот.
Когда я просил поискать упоминание о сигнатуре( стандарта под рукой  не было) я  предполагал, что там окажется четкая фраза: типа  " в сигнатуру  входит список типов параметров, при этом для функции члена класса в этот список входит тип  "указатель на класс-владелец", модифицированный в соответствии с cv-спецификатором, если он указан" А на самом деле они для разработчиков компиляторов оставили простор для творчества, указав только,что в сигнатуру входит cv спецификаторы.
Если посмотрите 9.3.2 This pointer
то там просто говорится, что в тип this модифицируется в соответствии с cv-спецификатором, если он есть и  нигде не говорится, каким образом pointer попадает  в функцию: через параметры первым параметром, последним или еще как. То есть я в принципе могу разработать компилятор, который параметры будет передавать через стек,  указатель на this через регистр или при вызове методов буду записывать его в   определеному   адресу.
Когда в С++ не было указателя на метод класса Страструп приводил такой пример


 
Код

 
   #include «stream.h»
   struct cl {
                  char* val; 
                  void print(int x) { cout «„ val «« x «« «\n“; }; 
                  cl(char* v) { val = v; };
    };
   // фальшивый'' тип для функций членов: 
   typedef void (*PROC)(void*, int);
   main() 
  { cl z1("z1 "); 
     cl z2("z2 "); 
     PROC pf1 = PROC( &z1.print); 
     PROC pf2 = PROC( &z2.print); z1.print(1); 
     (*pf1)( &z1,2); 
     z2.print(3); (*pf2)( &z2,4); 
  }



Но давал такой комментарий
Цитата

Поэтому в текущей реализации приходится жульничать, используя трюки. Что касается примера, который приводится ниже, то не гарантируется, что он будет работать. Используемый трюк надо локализовать, чтобы программу можно было преобразовать с использованием соответствующей языковой конструкции, когда появится такая возможность. Этот трюк использует тот факт, что в текущей реализации  this реализуется как первый (скрытый) параметр функции члена

С тех времен реализация не изменилась, но , если я не ошибаюсь,  в стандарте требование передачи this первым параметром не застолбили, а следовательно возможны и другие реализации компиляторов.

Добавлено @ 13:11
Цитата(vinter @  13.11.2008,  12:30 Найти цитируемый пост)
ы уже 3-ю страницу спорите ни о чем smile, н 

А  с этим я согласен  smile 

Автор: mes 13.11.2008, 15:41
Цитата(Vyacheslav @  13.11.2008,  13:10 Найти цитируемый пост)
И я пока не нашел упоминание, что для function members в список параметров входит скрытый  параметр(


method(i); это сокращенная запись от (*this).method(i); где this является таким же полноправным параметром как и i. 
запись теоритечески  могла бы выглядить так method(*this).(i); или method(i).(*this); на случай если пугает положение скобок до имени функции.


Цитата(Vyacheslav @  13.11.2008,  13:10 Найти цитируемый пост)
И я пока не нашел упоминание, что для function members в список параметров входит скрытый  параметр

слово "скрытый" к делу не относится - потому что оно действительно относится к способу передачи.
Главное что this является параметром, что ИМХО следует из нижеуказанных абзацев.

Цитата

9.3.1
1 A nonstatic member function may be called for an object of  its  class
  type,  or  for an object of a class derived (_class.derived_) from its
  class  type,  using  the  class  member  access  syntax  ...
5.2.2 ...
Note: a member function call of the form f()
  is  interpreted  as  (*this).f() 


Автор: J0ker 13.11.2008, 19:02
Vyacheslav, да все это было-бы правильно, если-бы я в первом посте, на который вы задали некорректный вопрос, не упомянул сигнатуру

Добавлено @ 19:06
Цитата(Vyacheslav @  13.11.2008,  13:10 Найти цитируемый пост)
Если посмотрите 9.3.2 This pointer
то там просто говорится, что в тип this модифицируется в соответствии с cv-спецификатором

неправда
он не модифицируется - он "is" - cv-спецификатор в этом случае - это спецификатор this И НИЧЕГО ДРУГОГО!!! он больше ни для чего не нужен! формально, это спецификатор одного из параметров, который не участвует в списке параметров. И это так-же единственная причина, почему тип функции-не-мембера не может использоваться как тип функции-мембера!!!
"
If the member function is declared const, the type of this is const X*, ...
"

Автор: Vyacheslav 13.11.2008, 19:33
Цитата(J0ker @  13.11.2008,  19:02 Найти цитируемый пост)
Vyacheslav, да все это было-бы правильно, если-бы я в первом посте, на который вы задали некорректный вопрос, не упомянул сигнатуру

При самой первой формулировке   вопроса http://forum.vingrad.ru/index.php?showtopic=235708&view=findpost&p=1696710 я процитировал и воспользовался Вашим определением  smile , где  о сигнатуре  ни слова. Я бы не стал жульничать, но в процентах 90 на собеседовании обычно дают именно такой ответ. И следующим моим вопросом обычно является вопрос, как разработчики STL ухитрились в map вставить два метода с одинаковыми именами и списком параметров. 


Автор: warmonger_ 13.11.2008, 20:12
первая страница форума интересна, потом - не понятно... споры...
давайте еще вопросов)

Автор: J0ker 13.11.2008, 20:18
Цитата(Vyacheslav @  13.11.2008,  19:33 Найти цитируемый пост)
При самой первой формулировке   вопроса здесь я процитировал и воспользовался Вашим определением

вы его вырвали из контекста
Цитата(J0ker @  12.11.2008,  19:13 Найти цитируемый пост)
переопределение (overriding) - это создание в классе потомке функции с той-же сигнатурой, что и в классе предке
перегрузка (overloading) - это создание функций с одним именем но разными наборами параметров в одном неймспейсе


единственное к чему тут можно придраться, так это упоминания класса в определении переопределения

Цитата(Vyacheslav @  13.11.2008,  19:33 Найти цитируемый пост)
И следующим моим вопросом обычно является вопрос, как разработчики STL ухитрились в map вставить два метода с одинаковыми именами и списком параметров. 

данный вопрос некорректен - константность функции определяет константность одного из аргументов - каким образом этот аргумент попадает в функцию и как к нему происходит обращение рояля не играет - достаточно того, что аргумент присутствует

Добавлено через 5 минут и 33 секунды
Цитата(warmonger_ @ 13.11.2008,  20:12)
первая страница форума интересна, потом - не понятно... споры...
давайте еще вопросов)

офтопиковый вопрос
определить зацикленность односвязного списка (для начала)

Автор: Vyacheslav 13.11.2008, 21:05
Спор стал бессмысленым
Можно простой вопрос  smile 
Сколько параметров какого типа в методе A::func(int, int)?


Автор: mes 13.11.2008, 21:26
Цитата(Vyacheslav @  13.11.2008,  21:05 Найти цитируемый пост)
Сколько параметров какого типа в методе A::func(int, int)?

static или обычная ?  
у static два int`а
иначе два int`a и указатель на объект класса А
(чтоб лучше представить: попобуйте вызвать ее, имея указатель на вашу не-статичную функцию и не имея аргументов для упомянутых выше параметров )

Автор: Alek86 13.11.2008, 21:45
mes, а если функция в классе - виртуальном наследнике?

Автор: J0ker 13.11.2008, 22:06
Цитата(Vyacheslav @  13.11.2008,  21:05 Найти цитируемый пост)
Сколько параметров какого типа в методе A::func(int, int)?

для нестатической функции-члена - в деклараторе параметров - два int, и в деклараторе самой функции - один A*
попробую объяснить на примере
Код

class A
{
private:
    int a;
public:
    A(int _a): a(_a) {}
    int sum(int b) { return a+b; }
};

A a1(12);
A a2(25);

cout << a1.sum(2) << endl;
cout << a2.sum(2) << endl;

а теперь вопрос - почему при абсолютно идентичном вызове абсолютно идентичных функций (фактически одной и той-же функции), мы получаем разный результат?
ответ (выбрать правильный):
- функция A::sum недетерминирована
- функция A::sum вызвана с разными фактическими параметрами
 smile

Добавлено через 3 минуты и 37 секунд
Цитата(Alek86 @ 13.11.2008,  21:45)
mes, а если функция в классе - виртуальном наследнике?

а чем у нас виртуальные наследники хуже?  smile 

Автор: Annihilator 13.11.2008, 22:10
Цитата(warmonger_ @  14.11.2008,  00:12 Найти цитируемый пост)
давайте еще вопросов)

Простой совсем вопрос
"Какова сложность алгоритма вставки элемента в конец вектора"

Автор: mes 13.11.2008, 22:12
Цитата(J0ker @  13.11.2008,  22:06 Найти цитируемый пост)
а теперь вопрос - почему при абсолютно идентичном вызове абсолютно идентичных функций (фактически одной и той-же функции), мы получаем разный результат?

пример в десяточку!  smile 

Автор: warmonger_ 13.11.2008, 23:19
Цитата(Annihilator @  13.11.2008,  21:10 Найти цитируемый пост)
"Какова сложность алгоритма вставки элемента в конец вектора" 

O(1)?

Автор: J0ker 14.11.2008, 01:07
Цитата(warmonger_ @ 13.11.2008,  23:19)
Цитата(Annihilator @  13.11.2008,  21:10 Найти цитируемый пост)
"Какова сложность алгоритма вставки элемента в конец вектора" 

O(1)?

не всегда
зависит от того, есть ли зарезервированное место или требуется реаллокация

Автор: JackYF 14.11.2008, 19:13
J0ker, амортизированое O(1).

Автор: J0ker 14.11.2008, 19:49
Цитата(JackYF @  14.11.2008,  19:13 Найти цитируемый пост)
J0ker, амортизированое O(1). 

а че Джокер-то сразу
вопрос не я задавал  smile 

на мой вопрос так никто и не ответил  smile 

Автор: mes 14.11.2008, 22:26
Цитата(J0ker @  14.11.2008,  19:49 Найти цитируемый пост)
на мой вопрос так никто и не ответил  smile  

перелистал всю тему вновь но не нашел... я дико извиняюсь, но не могли бы Вы повторно его озвучить ?  smile 

Автор: vinter 14.11.2008, 22:33
Цитата(mes @  14.11.2008,  23:26 Найти цитируемый пост)
перелистал всю тему вновь но не нашел... я дико извиняюсь, но не могли бы Вы повторно его озвучить ?  


Цитата(J0ker @  13.11.2008,  21:18 Найти цитируемый пост)
определить зацикленность односвязного списка (для начала)


Автор: mes 14.11.2008, 22:49
Цитата(vinter @  14.11.2008,  22:33 Найти цитируемый пост)
определить зацикленность односвязного списка (для начала)

я так понимаю иметеся ввиду зацикленость конца на начала, а не замыкания в середине 
Код

  добавляем "себя" (свой элемент) в список,
  идем по списку :
     если встретился конец списка, то цикла нет
     если нашли "себя", то зациклены
  удаляем "себя" из списка

Так ?

другую загадку я слышал от Alek86, привожу по памяти
Цитата

определить кол-во элементов в очереди, у которой доступны только следующие методы: pop_first(), push_first(), push_back(), pop_back()
и фиксированое кол-во (малое относительно вероятных размеров очереди) дополнительной памяти. 
примечание : очередь в итога должна иметь прежний  (неизменный) вид. 


Автор: vinter 14.11.2008, 23:00
ммм pop_first  в буфер, потому пуш его обратно и потом поп_бэк пока не найдем первый элемент?

Автор: mes 14.11.2008, 23:02
Цитата(vinter @  14.11.2008,  23:00 Найти цитируемый пост)
ммм pop_first  в буфер, потому пуш его обратно и потом поп_бэк пока не найдем первый элемент? 

а как узнаем какой первый ?  smile 

Автор: J0ker 15.11.2008, 01:31
Цитата(mes @  14.11.2008,  22:49 Найти цитируемый пост)
я так понимаю иметеся ввиду зацикленость конца на начала, а не замыкания в середине 

именно на середину smile 
у то уж как-то просто получается

Добавлено @ 01:39
Цитата(mes @  14.11.2008,  22:49 Найти цитируемый пост)
определить кол-во элементов в очереди, у которой доступны только следующие методы: pop_first(), push_first(), push_back(), pop_back()
и фиксированое кол-во (малое относительно вероятных размеров очереди) дополнительной памяти

такую очередь можно отсортировать используя указанные операции с помощью алгоритма ханойская башня, используя один конец как источник, а другой - как приемник, а потом последовательным извлечением с одного конца и запихиванием в другой можно определить длину очереди
но наскока я понимаю данный алгоритм не сработает с очередью состоящей из равных элементов

Автор: mes 15.11.2008, 01:41
Цитата(J0ker @  15.11.2008,  01:31 Найти цитируемый пост)
но наскока я понимаю данный алгоритм не сработает с очередью состоящей из равных элементов

ага. плюс забыл сказать, что очередь надо вернуть в исходном виде

Добавлено через 13 минут и 20 секунд
Цитата(J0ker @  15.11.2008,  01:31 Найти цитируемый пост)

именно на середину smile 
у то уж как-то просто получается

то есть надо найти петлю ? а какие ограничения в условии?

ну например первый вариант пришедший в голову :
просто  упорядочить по next() и споткнемся на узле петли.


Автор: J0ker 15.11.2008, 02:29
Цитата(mes @  15.11.2008,  01:41 Найти цитируемый пост)
то есть надо найти петлю ? а какие ограничения в условии?

надо определить, что петля есть (либо что нет)
список неопределенной длины, возможно очень большой
памяти доступно как всегда немного
список менять нельзя
вообще задача классическая и имеет классическое решение
просто у меня есть неклассическое продолжение... но подожду пока ответят на этот вопрос  smile 

Автор: J0ker 15.11.2008, 03:21
Цитата(mes @  15.11.2008,  01:41 Найти цитируемый пост)
ага. плюс забыл сказать, что очередь надо вернуть в исходном виде

алгоритм следующий
(буду называть голову верхом а хвост низом - мне так проще думается  smile )
для начала нам надо сделать так, что-бы с одного конца, допустим снизу, было два неравных элемента - например путем перестановки элементов вниз или вверх, либо добавлением заведомо неравного элемента вниз - все это потом просто восстанавливается - при этом определяем, что длина очереди заведомо не меньше 2
1. изымаем сверху и переставляем вниз один элемент
2. запоминаем следующий сверху
3. переставляем снизу один обратно
4. меняем местами снизу 2 элемента
5. изымаем сверху и переставляем вниз один элемент
6. сравниваем следующий сверху с запомненным на шаге 2 - разные элементы - конец

далее проделываем операции 1-6 с 2-мя, 3-мя, ... , n элементами, пока на шаге 6 мы не обнаружим разные элементы
при необходимости восстанавливаем положение нижних элементов

Добавлено через 2 минуты и 53 секунды
ЗЫЖ да, и с хонойской башней я там перемудрил - сортируется гораздо проще... не подумав ляпнул, сорри

Автор: mes 15.11.2008, 05:19
Цитата(J0ker @  15.11.2008,  02:29 Найти цитируемый пост)
но подожду пока ответят на этот вопрос  smile 


проверять себя (метку) по указателю можно ?

делаем по списку N шагов, ставим метку и  идем дальше столько же шагов, 
если ни конец, ни метка не встретились - увеличиваем N нa M, переносим метку  и повторяем сначала.
попав в петлю мы оттуда не выберемся, и найдется она тогда, когда N будет больше длины петли.

оптимальнее будет использовать не одну, а несколько меток, сколько позволит доп. память.

Автор: J0ker 15.11.2008, 06:24
Цитата(mes @  15.11.2008,  05:19 Найти цитируемый пост)
делаем по списку N шагов, ставим метку и  идем дальше столько же шагов, 
если ни конец, ни метка не встретились - увеличиваем N нa M, переносим метку  и повторяем сначала.
попав в петлю мы оттуда не выберемся, и найдется она тогда, когда N будет больше длины петли.

идея правильная, но не оптимальная

Цитата(mes @  15.11.2008,  05:19 Найти цитируемый пост)
оптимальнее будет использовать не одну, а несколько меток, сколько позволит доп. память.

даю подсказку - двух достаточно, необходимо N и M выразить конкретнее  smile 

Автор: vinter 15.11.2008, 08:36

Цитата(mes @  15.11.2008,  00:02 Найти цитируемый пост)
а как узнаем какой первый ? 

Цитата(vinter @  15.11.2008,  00:00 Найти цитируемый пост)
pop_first  в буфер, потому пуш его обратно 

в буфере у нас первый элемент smile

Автор: mes 15.11.2008, 12:02
Цитата(vinter @  15.11.2008,  08:36 Найти цитируемый пост)
в буфере у нас первый элемент smile 

вот для примера содержимое очереди :  1,2,1,2,3,1,2,3,1 
Цитата(vinter @  15.11.2008,  08:36 Найти цитируемый пост)
pop_first  в буфер 

ну получили мы 1..
Цитата(vinter @  14.11.2008,  23:00 Найти цитируемый пост)
pop_first  в буфер, потому пуш его обратно и потом поп_бэк пока не найдем первый элемент? 

и как узнать при каком 1 у нас сннова первый элемент ?

Добавлено через 7 минут и 37 секунд
Цитата(J0ker @  15.11.2008,  06:24 Найти цитируемый пост)
даю подсказку - двух достаточно, необходимо N и M выразить конкретнее  smile  

предполагаем что длина списка Х,  тогда N = X/2, метки одна вначале другая в середине.
если не угадали, предполагаем, что  размер (думаю) в два раза больше, увеличиваем соответственно N и аналогично переставляем метки.

Автор: mes 15.11.2008, 12:36
Цитата(J0ker @  15.11.2008,  03:21 Найти цитируемый пост)
1. изымаем сверху и переставляем вниз один элемент
2. запоминаем следующий сверху
3. переставляем снизу один обратно
4. меняем местами снизу 2 элемента
5. изымаем сверху и переставляем вниз один элемент
6. сравниваем следующий сверху с запомненным на шаге 2 - разные элементы - конец


ага.

буду использовать словосочетание "идем с начала конец " как циклический pop_first и push_back 
и слово "возвращаемся" как обратные действия.

Код

запоминаем с конца 1й как Х
идем с начала в конец пока не встретим Х, меняем элемент на другой и возвращаемся.
смотрим с конца 1й, если изменился - значит нашли, меняем его на Х
иначе повторяем заход, не обращая на те элементы, которые мы проверили в прошлый раз
(и исправляя тот элемент, что заменили)


Автор: J0ker 15.11.2008, 18:14
Цитата(mes @  15.11.2008,  12:02 Найти цитируемый пост)
предполагаем что длина списка Х,  тогда N = X/2, метки одна вначале другая в середине.
если не угадали, предполагаем, что  размер (думаю) в два раза больше, увеличиваем соответственно N и аналогично переставляем метки.

вобщем ответ принят, хотя он не оптимален, идея правильная
классическое решение - взять два итератора, и перемещать их с разной скоростью, обычно второй - в 2 раза быстрей - т.е. первый перемещаем на 1 элемент, а второй перемещаем на 2 элемента. На каждом шаге проверяем встретились ли они. Если быстрый итератор добрался до конца списка - цикла нет, если добрался до медленного - цикл есть.
А теперь продолжение.

Починить список  smile 

Автор: mes 15.11.2008, 19:51
Цитата(J0ker @  15.11.2008,  18:14 Найти цитируемый пост)
взять два итератора, и перемещать их с разной скоростью

надо взять на вооружение.. в эту сторону я не думал. )

Автор: Ln78 16.11.2008, 08:48
J0ker, я не понял задачу про список. Во-первых, какие методы доступны, явно не указано. Если итератор мы можем создать, то, как я понимаю, begin() доступен? И end() тоже? А почему тогда size() недоступен? И потом, если этот список у нас такой странный, что содержит петлю внутри, где гарантия, что next() работает правильно? Как-то задача изначально нечётко поставлена. И что означает починить? Разорвать цикл, но при этом смириться с тем, что хвост потерян безвозвратно? Что нам известно, можем ли мы как-то повлиять на результат, возвращаемый методом end()?

Автор: mes 16.11.2008, 12:44
Цитата(Ln78 @  16.11.2008,  08:48 Найти цитируемый пост)
J0ker, я не понял задачу про список. Во-первых, какие методы доступны, явно не указано. Если итератор мы можем создать, то, как я понимаю, begin() доступен? И end() тоже? А почему тогда size() недоступен? И потом, если этот список у нас такой странный, что содержит петлю внутри, где гарантия, что next() работает правильно?

Отвечу вместо автора : 

Код

begin() - возвращает первый элемент
end() - возвращает NULL
size () -  нету и не нужен для списка, для нашей задачи.
next () - работает правильно , но сам список поврежден.

В списке только один дефект - петля (это обнаружили в прошлом тестировании  :smile )).  То есть последний next() выдает не NULL , а ссылается на элемент списка.

Задача найти   элемент, next() которого  дефектный, чтоб востановить список и не потерять данных.


J0ker, надеюсь я правильно изложил  smile 


Автор: J0ker 16.11.2008, 19:24
Цитата(Ln78 @  16.11.2008,  08:48 Найти цитируемый пост)
J0ker, я не понял задачу про список.

Код

struct element
{
    element *next;
};

element *get_list();

int main()
{
    element *head = get_list();
}


Добавлено через 3 минуты и 13 секунд
Цитата(Ln78 @  16.11.2008,  08:48 Найти цитируемый пост)
И что означает починить?

последний элемент должен указывать в NULL (ну или в специальный итератор end)

Цитата(Ln78 @  16.11.2008,  08:48 Найти цитируемый пост)
Разорвать цикл, но при этом смириться с тем, что хвост потерян безвозвратно?

он не будет потерян
нарисуйте себе картинку и подумайте

Добавлено через 4 минуты и 34 секунды
Цитата(mes @  16.11.2008,  12:44 Найти цитируемый пост)
J0ker, надеюсь я правильно изложил

да правильно

Автор: Vyacheslav 17.11.2008, 19:29
Этот вопрос задаю на понимание , что такое lvalue / rvalue
Вопрос задается в следующим виде.

Будет различаться результаты работы двух фрагментов кода и если будут, то почему?

Код

  int i = 5;
  ++i +=1;
  cout <<  i;

и
Код

  int i = 5;
  i++ +=1;
  cout <<  i;


Добавлено @ 19:32
Один из стандартных вопросов: рассказать, существуют ли какие либо особенности, которые нужно учитывать, при вызове виртуальных функций в конструкторе и деструкторе.

Автор: Vyacheslav 17.11.2008, 19:46
Как  в производном класса  без переопределения   "открыть" ( сделать public )   метод, защищенный(  protected )  в базовом классе классе

Код

struct  A 
{
  protected:
    void func();     
};

struct B : public A
{
     public:
       /* void func();  ????  */ 
};

Автор: Vyacheslav 17.11.2008, 20:19
Ну и если , кандидат уже  по результатам интервью уже прошел, а время еще есть, то можно  задать и такой вопрос для выяснения эрудиции кандидата.   

Результат работы программы

Код

#include <iostream>

struct  A
{
    int m_; 
    A(): m_(5)  { throw 1; }
};
struct B : public A
{
    B() try : A() {} catch(...){}
};

int main()
{
    try{
            B b;
            std::cout << b.m_ << std::endl;
    } catch(...) {   std::cout << "exception" << std::endl;    }
 return 0;
}



 

Автор: mes 17.11.2008, 23:04
Цитата(Vyacheslav @  17.11.2008,  19:29 Найти цитируемый пост)
Будет различаться результаты работы двух фрагментов кода и если будут, то почему?

будет из за замены  префиксного на постфиксный (не помню как слово звучит) оператора

Цитата(Vyacheslav @  17.11.2008,  19:29 Найти цитируемый пост)
при вызове виртуальных функций в конструкторе и деструкторе. 

вызывается не виртуальная реализация . т.е реализация определенная в классе , в каком она вызвана в конструкторе.

Цитата(Vyacheslav @  17.11.2008,  19:46 Найти цитируемый пост)
  без переопределения   "открыть

using в помощь

Автор: warmonger_ 18.11.2008, 00:54
Цитата(Vyacheslav @  17.11.2008,  18:46 Найти цитируемый пост)
Как  в производном класса  без переопределения   "открыть" ( сделать public )   метод, защищенный(  protected )  в базовом классе классе

Код

struct  A 
{
  protected:
      void func() { std::cout<<"A::funс()"<<std::endl; }     
};
struct B : public A
{
     public:
         void func() { A::func(); }
};

int main(int argc, char **argv)
{
    B b;
    b.func();

    return 0;
}


Добавлено через 2 минуты и 55 секунд
Цитата(Vyacheslav @  17.11.2008,  18:29 Найти цитируемый пост)
Будет различаться результаты работы двух фрагментов кода и если будут, то почему?

будут в том смысле, что второй работать не будет ибо не lvalue i++

Автор: vinter 18.11.2008, 08:42
Цитата(warmonger_ @  18.11.2008,  01:54 Найти цитируемый пост)
struct B : public A{     public:         void func() { A::func(); }};

я тоже только до такого допер, но 
Цитата(warmonger_ @  18.11.2008,  01:54 Найти цитируемый пост)
без переопределения

и еще, что получается с эксепшеном? Конструктор B бросает исключение, из-за того, что A не был корректно создан, или как?

Автор: MAKCim 18.11.2008, 09:19
Цитата(Vyacheslav @  17.11.2008,  20:19 Найти цитируемый пост)
Результат работы программы

имхо, вызов terminate


Автор: Vyacheslav 18.11.2008, 12:03
Подводим итоги:
1.Этот фрагмент не откомпилится. Потребует, чтобы было lvalue
Код

int i = 5;
  i++ +=1;  // error
  cout <<  i;


2. Формально говоря, виртуальные функции при вызове в конструкторе и деструкторе ведут себя аналогично невиртуальным.

3. 
  public:
      using A::func;

4. программа выведет на консоль сообщение  "exception". Несмотря, что function try-block в конструкторе отловит исключение, но перегенерит  его при условии,  если программист сам не удосужится сгенерить свое новое исключение.
В выше приведенном примере выражение 
Код

B()try:A(){}catch(...){ } 

эквивалентно 
Код

B()try:A(){}catch(...){ throw; } 


В  нижеприведенном примере  идет подмена одного типа исключение на другой. 
В результата  программа выдаст сообщение "constuctor error" . Первоначально сгенеренное в теле конструктора исключение погасится. Вернее -  не "погасится", а до кода его регенерации дело просто не дойдет. 
Код

struct  A
{
    int m_; 
    A(): m_(5)  { throw 1; }
};
struct B : public A
{
    B()try:A(){}catch(...){ throw "constuctor error";  } 
};
int main()
{
    try{
    B b;
    std::cout << b.m_ << std::endl;
    } 
    catch( char* c)
    {
        std::cout << c << std::endl;            
    }
    catch(...)
    {
        std::cout << "exception" << std::endl;
    }
 return 0;
}



Автор: mes 18.11.2008, 12:25
Цитата(Vyacheslav @  18.11.2008,  12:03 Найти цитируемый пост)
В выше приведенном примере выражение 

B()try:A(){}catch(...){ } 

эквивалентно 

B()try:A(){}catch(...){ throw; } 

я с исключениями пока не знаком, но интересно, на каком основании эти две строчки кода эквивалентны ?


Автор: vinter 18.11.2008, 12:31
Цитата(mes @  18.11.2008,  13:25 Найти цитируемый пост)
я с исключениями пока не знаком, но интересно, на каком основании эти две строчки кода эквивалентны ?

я так понимаю на основании того, что объект все таки не был сконструирован.

Автор: Vyacheslav 18.11.2008, 13:10
Цитата(mes @  18.11.2008,  12:25 Найти цитируемый пост)
я с исключениями пока не знаком, но интересно, на каком основании эти две строчки кода эквивалентны ?

Эквивалентны по поведению  smile  
На основании того, что в соответствии со стандартом, при достижении конца  блока обработчика ( catch (...) {} ) в  funtion-try-block конструктора и деструктора перехваченное исключение будет   сгенерено( rethrow)  заново, то есть фактически будет вызвано throw; 
(15.3 пункт 16)

Автор: Vyacheslav 18.11.2008, 13:26
Кстати по исключениям
Результат работы  программы?
Код

void func() throw(int) { throw "func error"; }

int main()
{
    try{
        func();
    }
     catch( char* c )
    {
          std::cout << c << std::endl;
    }
     catch(int)
    {
        std::cout << "exception" << std::endl;
    }
 return 0;
}



Добавлено @ 13:30

Чему эквивалентно объявление функции?
Код

void func();

Этому 
Код

void func() throw();

или этому
Код

void func() throw(...);

Автор: vinter 18.11.2008, 14:01
Цитата(Vyacheslav @  18.11.2008,  14:26 Найти цитируемый пост)
Результат работы  программы?

теоретически termination()(вроде), практически func error, по крайней мере для студии, плевать студия хотела на спецификацию ))

Цитата(Vyacheslav @  18.11.2008,  14:26 Найти цитируемый пост)
Чему эквивалентно объявление функции?


Цитата(Vyacheslav @  18.11.2008,  14:26 Найти цитируемый пост)
void func() throw(...);


Автор: Vyacheslav 18.11.2008, 15:06
Цитата(vinter @  18.11.2008,  14:01 Найти цитируемый пост)
теоретически termination()(вроде), практически func error, по крайней мере для студии, плевать студия хотела на спецификацию ))

По этому я обычно стараюсь при интервью держаться в рамках стандарта  smile

Автор: warmonger_ 18.11.2008, 18:13
Цитата(vinter @  18.11.2008,  13:01 Найти цитируемый пост)
теоретически termination()(вроде), практически func error, по крайней мере для студии, плевать студия хотела на спецификацию ))

а почему студия выводит func error? это как-то объясняется?

Автор: Vyacheslav 18.11.2008, 18:25
А вот захаянный  Builder 6 в этом случае выдает результат в соответствии со стандартом smile

Автор: vinter 18.11.2008, 18:33
Цитата(warmonger_ @  18.11.2008,  19:13 Найти цитируемый пост)
а почему студия выводит func error? это как-то объясняется?

студия игнормрует спецификаторы генерируемых исключений в сигнатуре функций, можно использовать как комментарии smile

Автор: warmonger_ 18.11.2008, 19:09
Цитата(vinter @  18.11.2008,  17:33 Найти цитируемый пост)
студия игнормрует спецификаторы генерируемых исключений в сигнатуре функций, можно использовать как комментарии smile 

точно... я раньше и не знал)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)