2010-08-09 2 views
5
//Using g++ and ubuntu. 
#include <vector> 
using namespace std; 

Определение класса:C++ векторов классов с конструкторами

class foo(){ 
(...) 
foo(int arg1, double arg2); 
} 

Constructor:

foo::foo(int arg1, double arg2){ 
(...) //arrays whose length depend upon arg1 and arg2 
} 

Я хотел бы сделать что-то вроде этого:

vector<foo> bar(10); //error: no matching function for call to 'foo::foo()' 
bar[0] = new foo(123, 4.56); 
(...) 

Альтернатива метод (который мне меньше нравится) - использовать push_back:

vector<foo> bar; //works 
bar.push_back(new foo(123, 4.56)); //throws similar error. 
//Omitting the "new" compiles but throws a "double free or corruption (fasttop)" on runtime. 

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

ответ

4

Почему вы используете new, если не требуется создание динамической памяти? Конечно, использование new потерпит неудачу, в результате получится foo*, когда push_back принимает foo. (В конце концов, у вас есть вектор.)

Что случилось с push_back? Если вы хотите зарезервировать память спереди, используйте reserve(); предоставление числа в конструкторе vector делает много копий второго параметра (который неявно foo(), что не сработает, следовательно, ваши ошибки), что не то же самое, что просто резервировать память.

Если вы делаете что-то правильно (нет new), сбои возникают в вашем коде, а не в векторе. Вы, наверное, не написал собственный класс, который управляет ресурсами. * (Помните The Big Three используйте copy-and-swap idiom.)

* Я говорю это потому, что вы говорите «//arrays whose length depend upon arg1 and arg2 », который я подозреваю, что означает, что у вас есть new[] в классе где-то , Без Большой тройки ваше управление ресурсами не удастся.

Вы все равно не должны управлять ресурсами, классы несут одну ответственность. Это означает, что он должен быть либо динамическим массивом, либо использовать динамический массив, но не управлять ими и использовать динамический массив. Таким образом, распределите ресурсы в свой класс, а затем создайте другой класс (ваш), который их использует. Динамический массив - это std::vector, поэтому вы уже сделали это. Любое время, когда вам нужен динамический массив, используйте vector; никогда не бывает причин.

+0

+1 за очень хороший ответ. Если бы я мог, я хотел бы дать дополнительный +1, не говоря о том, что вы всегда должны использовать std :: vector, но что вы всегда должны использовать вектор. – Simon

0

std :: vector всегда создает элементы на основе конструктора по умолчанию, который вы не определили в фрагменте выше.

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

4
vector<foo> bar(10); //error: no matching function for call to 'foo::foo()' 

Это не удается, потому что std::vector конструктор вы звоните,

explicit vector (size_type n, const T& value= T(), const Allocator& = Allocator()); 

Как вы можете видеть, он пытается заполнить вектор с 10 вызовами конструктора по умолчанию foo, который не делает существовать.

Кроме того, все ваши примеры с изображением new потерпят неудачу, потому что вектор ожидает объекта типа foo, а не foo *. Кроме того, смена на vector<foo *> приведет к сбою, если вы вручную не указали delete каждого члена перед очисткой вектора. Если вы действительно хотите перейти по пути распределения динамической памяти, создайте vector< shared_ptr<foo> >. shared_ptr доступен в Boost libraries, или если ваш компилятор включает библиотеки TR1, он будет присутствовать в заголовке <memory> в пространстве имен std::tr1, или если ваш компилятор имеет библиотеки C++ 0x, он будет доступен в самом пространстве имен std.

То, что вы, вероятно, следует сделать следующее:

vector<foo> bar; 
bar.reserve(10); 
bar.push_back(foo(1, 2)); 
... 
... 
bar.push_back(foo(10, 20)); //10 times 
+0

Возможно, следует упомянуть, что shared_ptr является частью библиотек boost или C++ 0x –

+0

Это само по себе не работает, но мне нужно иметь большой 3. –

+0

@Kevin: Я подозреваю, что вы должны использовать 'std :: vector' так вы этого не делаете. Используйте фактор-ресурс от использования, не делайте того и другого. – GManNickG

Смежные вопросы