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


Автор: Folk 25.5.2008, 08:14
Всем доброго времени суток.

Прошу пояснить некоторую ситуацию. Я использую VS 2005, хотя думаю это непринципиально.

Есть такой простой класс:

Код

class A
{
public:
    A() 
    {
        std::cout << "First constructor." << std::endl;
    };

    A(int val) 
    {
        std::cout << "Second constructor." << std::endl;
        b = val;
    };

    ~A() 
    {
        std::cout << "Destructor." << std::endl;
    }

    void print_b() const 
    {
        std::cout << b << std::endl;
    }

private:
    int b;
};


Если сделать так:

Код

std::vector<A> ar;

ar.push_back(0);
ar[0].print_b();

std::cout << ar.size() << std::endl;

return 0;


то в консоли увидим:

Цитата

Second constructor.
Destructor.
Destructor.
0
1
Destructor.


Откуда взялись два вызова дуструктора после создания объекта? 

И ещё, если сделать так:

Код

std::vector<A> ar;

ar.assign(5, 0);
ar[0].print_b();

std::cout << ar.size() << std::endl;

return 0;


То в консоли видим:

Цитата

Second constructor.
Destructor.
Destructor.
Destructor.
0
5
Destructor.
Destructor.
Destructor.
Destructor.
Destructor.


Тут два вопроса:

1. Почему конструктор вызван единожды?
2. Опять же, откуда 3 вызова дектрукторов сразу после создания объектов?

Заранее спасибо.

Автор: anatox91 25.5.2008, 08:38
по-моему это разрушается еще и временный объект

Автор: mes 25.5.2008, 10:41
Цитата(Folk @  25.5.2008,  08:14 Найти цитируемый пост)
1. Почему конструктор вызван единожды?
2. Опять же, откуда 3 вызова дектрукторов сразу после создания объектов?


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

Код

class A
{
public:
    A()
    {
        std::cout << "First constructor." << std::endl;
    };

    A(int val)
    {
        std::cout << "Second constructor." << std::endl;
        b = val;
    };

    A(const A& a)
    {
        std::cout << "Copy constructor." << std::endl;
        b=a.b;
    }
    ~A()
    {
        std::cout << "Destructor." << std::endl;
    }

    void print_b() const
    {
        std::cout << b << std::endl;
    }

private:
    int b;
};

Автор: Folk 25.5.2008, 11:08
Цитата(mes @  25.5.2008,  10:41 Найти цитируемый пост)
Не забываем про то, что бывают конструкторы по умолчанию и для подобных тестов их надо перегрузить :


Ага, тогда с твоим вариантом класса и таким вот кодом:

Код

    std::vector<A> ar;

    ar.push_back(0);
    ar[0].print_b();
    std::cout << ar.size() << std::endl;

    return 0;


Получаем вот это:

Цитата

Second constructor.
Copy constructor.
Copy constructor.
Destructor.
Destructor.
0
1
Destructor.


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

Автор: Daevaorn 25.5.2008, 12:37
Цитата(Folk @  25.5.2008,  12:08 Найти цитируемый пост)
А если у меня массивные объекты, жрут много памяти и при копировании объекта требуется выполнение множества операций, то при одном добавлении такого объекта в вектор я получу огромную потерю просто из-за того, что он создаёт две временные копии?  

Да. Поэтому надо хранить указатели в каких-то обертках.

Автор: Folk 25.5.2008, 13:40
Цитата(Daevaorn @  25.5.2008,  12:37 Найти цитируемый пост)
Да. Поэтому надо хранить указатели в каких-то обертках.


Например? У меня как раз сейчас класс хранит в себе два достаточно больших массива. А массив этих классов хранится в векторе, 

Автор: mes 25.5.2008, 13:51
Цитата(Folk @  25.5.2008,  13:40 Найти цитируемый пост)
У меня как раз сейчас класс хранит в себе два достаточно больших массива.

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

Автор: Folk 25.5.2008, 15:19
Спасибо всем за ответы, теперь стало ясно! 

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