Fefer_Ivan's blog

By Fefer_Ivan, 13 years ago, In Russian

Доброе утро/день/вечер, Codeforces.

В этом посте я буду писать о тонкостях С++, которые лично мне кажутся интересными. Постараюсь выкладывать тонкости по одной штуке раз в 2 дня. Также, я надеюсь на то, что сообщество будет делиться своими знаниями С++ в комментариях. Ну, приступим:

  • 08.02.2012. Источник: С. Мейерс — Эффективное использование STL.
    Когда вы создаете статический массив из N объектов класса A (A arr[N]), для каждого элемента массива вызывается default конструктор. А когда вы создаете вектор из N объектов класса А (vector<A> arr(N)), то при помощи default конструктора будет создан временный объект, а для всех элементов массива будет вызван конструктор копирования от этого временного объекта.

  • 10.02.2012. Источник: придумал сам во время контеста.
    Предположим, что вы пихаете гов... сдаете рандомизированное решение и вам необходимо применить одинаковую случайную перестановку к двум различным массивам. Вот очень простой способ сделать это:

    srand(12345);
    random_shuffle(a, a + n);
    srand(12345);
    random_shuffle(b, b + n);

Извините, что не обновлял тему уже 7 дней. Мне было необходимо сдать экзамен по численным методам, который я пропустил из-за Петрозаводска. Сдал на 5 и теперь с чистой совестью продолжаю.

  • 18.02.2012. Источник: С. Мейерс — Эффективное использование C++.
    Тонкость не совсем олимпиадная, но очень интересная. Рассмотрим следующий код:
    #include <cstdio>

    class A{
    public:
        virtual void print(int p = 1){
            printf("A %d\n", p);
        }
    };

    class B : public A{
    public:
        virtual void print(int p = 30){
            printf("B %d\n", p);
        }
    };


    int main(){

        A* a = new A();
        a->print(); //Используется параметр по-умолчанию класса А, т.е. 1
        A* b = new B();
        b->print(); //Кажется, что используется параметр по-умолчанию класса B, т.е. 30

        return 0;
    }    

А теперь результат его исполнения: http://ideone.com/DcY4o.
При вызове виртуальной функции, функция выбирается в зависимости от динамического типа (то есть от типа объекта на который в данный момент указывает указатель), а параметры по-умолчанию — от статического типа (то есть определенного в момент объявления). По-этому, когда мы пишем A* b = new B(); b->print();, мы вызываем функцию класса B(динамический тип), но с параметром по-умолчанию класса А (статический тип).

Вопрос по маркапу: как увеличить уровень отступа у абзаца текста и как продолжить нумерованный список?

Продолжение следует...

  • Vote: I like it
  • +78
  • Vote: I do not like it