Interesting C/C++ interview questions

tchicago
Уже с Приветом
Posts: 1009
Joined: 16 Sep 2001 09:01
Location: USA

Post by tchicago »

A. Fig Lee wrote:Ну если на одном С++ программируешь... А если прыгаешь с С на С++ и обратно...
Лучше уж одного стиля придерживатся.

Code: Select all

#ifndef COPY_STRING
...
#endif


Unrelated. Чето я смотрел-смотрел на это, но так и не понял зачем делать это различие между c и с++. У Вас new/delete переопределены?
tchicago
Уже с Приветом
Posts: 1009
Joined: 16 Sep 2001 09:01
Location: USA

Post by tchicago »

шпиён wrote:
tchicago wrote:Зависит от:

a) Сложности объекта исключения. Во многих случаях это не просто несколько байт памяти.
б) Архитектуры приложения/библиотеки. Некоторые библитеки действительно используют механизм исключений для доставки пользователю результатов работы (с точки зрения разработчика библиотеки это исключительная ситуация, с точки зрения ее пользователя - нет)


А причем тут производительность? При таких условиях о ней УЖЕ мечтать не приходится.


Привести пример приложения? Таковые есть, и производительность тоже требуется. И достигается.

tchicago wrote:в) Наличия собственного аллокатора памяти или свойств стандартного.


Вам известны аллокаторы, производительность которых (на new И на delete) сравнима с отсутсвием аллокации? ;)


неверно поставлен вопрос. Надо так:
"Вам известны аллокаторы, производительность которых (на new И на delete) сравнима с производительностью конструктора копирования (и деструктора)?"
User avatar
roadman
Уже с Приветом
Posts: 707
Joined: 12 Mar 2003 22:29
Location: Moscow->Bay Area, CA

Post by roadman »

AndreyT wrote:
roadman wrote:Поскольку пользователь может создать класс нового exception exep_new на основе базового класса exep и при этом catch operator сработает также, однако delete операция вызовет деструктор базового класса. Ещё один пример, когда лучше объявить деструктор виртуальным в базовом классе


Не совсем понимаю, почему это "еще один" пример. Виртуальный деструктор, с формальной точки зрения, нужен тогда и только тогда, когда объект класса удаляется вот таким вот полиморфным образом. Так что это не "еще один" пример. Это просто очередная вариация одного и того же примера.


Не вдаваясь а подробности определения слова "пример" - по сути высказывания согласен.

А вот ещё вопрос по С++:

Могу я определить фукцию класса и virtual и inline одновременно, ну что-то типа:
class A
{
public:
inline virtual int get_type() { return 0; }
};

Вопрос(ы):
1. Если не могу, то почему?
2. Если могу, то будет ли inline работать или компилятор проигнорирует inline?
Функция маленькая и без virtual компилятор на 100% сделает её inline.
The philosophy of one century is the common sense of the next. --Henry Ward Beecher
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Post by AndreyT »

roadman wrote:А вот ещё вопрос по С++:

Могу я определить фукцию класса и virtual и inline одновременно, ну что-то типа:
class A
{
public:
inline virtual int get_type() { return 0; }
};


Да, можешь. В данном конкретном примере слово 'inline' излишне, ибо функция, определенная внутри определения класса и так является 'inline', но ошибки в этом нет.

Вопрос(ы):
1. Если не могу, то почему?


N/A, ибо можешь.

2. Если могу, то будет ли inline работать или компилятор проигнорирует inline?


Встраиваемость 'inline' функций в С++ проявляется на per-call basis. Т.е. один вызов одной и той же функции может встроиться, а другой - нет. Какой вызов встроится, а какой нет - зависит от условий, в которых происходит вызов, а также от способностей компилятора.

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

В тех же ситуациях, когда конкретноая целевая функция ясна уже в compile-time (известен динамический тип объекта или функция вызвана через квалифицированное имя) ничто не мешает компилятору выполнить встраивание. Большинство компиляторов так и поступает.
Best regards,
Андрей
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

tchicago wrote:
A. Fig Lee wrote:Ну если на одном С++ программируешь... А если прыгаешь с С на С++ и обратно...
Лучше уж одного стиля придерживатся.

Code: Select all

#ifndef COPY_STRING
...
#endif


Unrelated. Чето я смотрел-смотрел на это, но так и не понял зачем делать это различие между c и с++. У Вас new/delete переопределены?

Ну дак в одном случае бай дефоулт используем delete, а в С - используем free.
Поетому и разные. Чтоб не помнить как удалять. Чтоб не думать, когда программируешь. :wink:
Верить нельзя никому - даже себе. Мне - можно!
ig
Уже с Приветом
Posts: 491
Joined: 09 Apr 2000 09:01
Location: Tigard, OR

Post by ig »

roadman wrote:
class A
{
public:
inline virtual int get_type() { return 0; }
};

Вопрос(ы):
1. Если не могу, то почему?
2. Если могу, то будет ли inline работать или компилятор проигнорирует inline?
Функция маленькая и без virtual компилятор на 100% сделает её inline.

По идеи, если объект не вызывается через указатель или референс, то компилятор может встроить такую функцию (inline virtual).
User avatar
roadman
Уже с Приветом
Posts: 707
Joined: 12 Mar 2003 22:29
Location: Moscow->Bay Area, CA

Post by roadman »

AndreyT wrote:В тех же ситуациях, когда конкретноая целевая функция ясна уже в compile-time (известен динамический тип объекта или функция вызвана через квалифицированное имя) ничто не мешает компилятору выполнить встраивание. Большинство компиляторов так и поступает.

AndreyT, если Вы и дальше будете быстро и исчерпывающе отвечать на вопросы, то их будет неинтересно задавать :D . В футбол не играете?
The philosophy of one century is the common sense of the next. --Henry Ward Beecher
User avatar
adb
Уже с Приветом
Posts: 9275
Joined: 14 Dec 2001 10:01
Location: Российская Федерация

Post by adb »

tchicago wrote:Количества вызываемых конструкторов копирования.

А насчет char* - сорри, это я кажется Вас с Фигли перепутал.


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

Code: Select all

#include <string>

class myexception
{
public:

   myexception(){
       printf("ctor\n");
   }
   ~myexception(){
       printf("dtor\n");
   }

   myexception(const myexception& s){
       printf("ctor\n");
   }

private:
   std::string str;
};

void  foo1()
{
      throw myexception();
}

void foo()
{
   try{
    foo1();
   }catch(myexception &ex)
   {
       throw;
   }

}

void main()
{
   try{
    foo();
   }catch(myexception &ex)
   {
   }
}


Вывод при использовании &:
ctor
dtor

Без &:
ctor
ctor
ctor
dtor
dtor
dtor

Компилятор MSVC 6. Наверняка и стандарте что-нибудь есть по этому поводу, только лень искать.

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

P.S. Или я неправильно понял ваше утверждение?
tchicago
Уже с Приветом
Posts: 1009
Joined: 16 Sep 2001 09:01
Location: USA

Post by tchicago »

adb wrote:P.S. Или я неправильно понял ваше утверждение?


Оч странно. У меня все компиляторы вызывают конструктор копии. Один раз.
User avatar
adb
Уже с Приветом
Posts: 9275
Joined: 14 Dec 2001 10:01
Location: Российская Федерация

Post by adb »

tchicago wrote:
adb wrote:P.S. Или я неправильно понял ваше утверждение?


Оч странно. У меня все компиляторы вызывают конструктор копии. Один раз.


MSVC 7.0/Intel 8.0 у меня отработали также. Без копирования. Либо это оптимизация, либо несоотвествие стандарту.

У Меерса нашел это.
That leaves only catch-by-reference. Catch-by-reference suffers from none of the problems we have discussed. Unlike catch-by-pointer, the question of object deletion fails to arise, and there is no difficulty in catching the standard exception types. Unlike catch-by-value, there is no slicing problem, and exception objects are copied only once.
User avatar
шпиён
Уже с Приветом
Posts: 3459
Joined: 29 Oct 2002 20:08
Location: US

Post by шпиён »

tchicago wrote:
шпиён wrote:
tchicago wrote:Зависит от:

a) Сложности объекта исключения. Во многих случаях это не просто несколько байт памяти.
б) Архитектуры приложения/библиотеки. Некоторые библитеки действительно используют механизм исключений для доставки пользователю результатов работы (с точки зрения разработчика библиотеки это исключительная ситуация, с точки зрения ее пользователя - нет)


А причем тут производительность? При таких условиях о ней УЖЕ мечтать не приходится.


Привести пример приложения? Таковые есть, и производительность тоже требуется. И достигается.


Приложения, где требуется производительность и в критически-важном по скоросте месте происходит частый (сравнимый по частоте со внутренними итерациями) throw/catch? Ну приведите. Хотя мало ли неправильно написанного кода на свете.


tchicago wrote:
tchicago wrote:в) Наличия собственного аллокатора памяти или свойств стандартного.


Вам известны аллокаторы, производительность которых (на new И на delete) сравнима с отсутсвием аллокации? ;)


неверно поставлен вопрос. Надо так:
"Вам известны аллокаторы, производительность которых (на new И на delete) сравнима с производительностью инлайнового конструктора копирования копирующего vptrинлайнового пустого деструктора)?"


Вот так совсем правильно - можно отвечать. Только какая разница-то, если throw/catch все равно может быть сколь угодно долгим? :pain1:
User avatar
шпиён
Уже с Приветом
Posts: 3459
Joined: 29 Oct 2002 20:08
Location: US

Post by шпиён »

A. Fig Lee wrote:
tchicago wrote:
A. Fig Lee wrote:Ну если на одном С++ программируешь... А если прыгаешь с С на С++ и обратно...
Лучше уж одного стиля придерживатся.

Code: Select all

#ifndef COPY_STRING
...
#endif


Unrelated. Чето я смотрел-смотрел на это, но так и не понял зачем делать это различие между c и с++. У Вас new/delete переопределены?

Ну дак в одном случае бай дефоулт используем delete, а в С - используем free.
Поетому и разные. Чтоб не помнить как удалять. Чтоб не думать, когда программируешь. :wink:


Фигля, как уже не раз тут говорилось - не думать вредно. Вам привести разницу между malloc() и new[], или сами догадаетесь?
Почему бы Вам не использовать malloc() и в C++? :pain1:
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

шпиён wrote:Фигля, как уже не раз тут говорилось - не думать вредно. Вам привести разницу между malloc() и new[], или сами догадаетесь?
Почему бы Вам не использовать malloc() и в C++? :pain1:


Штирлиц, ну Вы даете! Я ж там и обьекты создаю, шо ж я теперь - для одного буду ню применять, а для другого - маллоk?
Голова опухнет. Инкапсулейшн знаете зачем - чтоб думать не надо было когда программируешь.
Верить нельзя никому - даже себе. Мне - можно!
User avatar
шпиён
Уже с Приветом
Posts: 3459
Joined: 29 Oct 2002 20:08
Location: US

Post by шпиён »

A. Fig Lee wrote:
шпиён wrote:Фигля, как уже не раз тут говорилось - не думать вредно. Вам привести разницу между malloc() и new[], или сами догадаетесь?
Почему бы Вам не использовать malloc() и в C++? :pain1:


Штирлиц, ну Вы даете! Я ж там и обьекты создаю, шо ж я теперь - для одного буду ню применять, а для другого - маллоk?
Голова опухнет. Инкапсулейшн знаете зачем - чтоб думать не надо было когда программируешь.


Ну если не думать - то и получится кю.
Возврат malloc() неплохо бы проверять. А new bad_alloc бросает. Хотите похожести - хоть new(nothrow) пишите.
User avatar
A. Fig Lee
Уже с Приветом
Posts: 12072
Joined: 17 Nov 2002 03:41
Location: английская колония

Post by A. Fig Lee »

шпиён wrote:Ну если не думать - то и получится кю.
Возврат malloc() неплохо бы проверять. А new no_memory бросает. Хотите похожести - хоть new(nothrow) пишите.


Штирлиц, если нет места для стринга, то там бесполезно проверять - надо память докупать.
Верить нельзя никому - даже себе. Мне - можно!

Return to “Работа и Карьера в IT”