2015-11-29 3 views
10

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

PointPtr centroids = new Point[k](5);

Ну, это не ошибка синтаксиса, но она не компилируется. Я действительно не хотел жестко закодировать «5» в конструкторе по умолчанию для Point. Есть идеи о том, как я должен это делать? Благодаря!

BTW, я сделал typedef Point *PointPtr где-то еще.

Извините, если заголовок не был точным. Я не знал, как это обобщить.

+2

Извините, вы не можете сделать это с помощью динамических массивов. Рассмотрим использование вектора, который позволяет использовать 'emplace_back' для построения объектов. –

+2

Еще одна причина, чтобы избежать «нового». –

+0

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

ответ

-5

Вы можете создать массив указателей (т.е. Point**) и инициализировать их в 2 этапа:

  1. создают массив:

    PointPtr* centroids = new PointPtr[k];

  2. Initialize:

    for (int i=0 ; i<k ; ++i) centroids[i]=new Point(5);

+1

Да нет. Это не Java. – szczurcio

+0

Знаешь, это может сработать! –

+1

Нет, это действительно не могло работать –

10

Я хотел бы предложить использовать std::vector:

std::vector<Point> v(k, Point{5}); 

Но вы также можете сделать это, как:

Point* centroids = new Point[5]{{1}, {2}, {3}, {4}, {5}}; 

Live Demo

+2

Я не знал об этом! –

+0

Не работает ли это не-векторное решение, если «Точка» не является совокупностью? – MicroVirus

+0

@MicroVirus Да, если вы предоставляете конструктор, который принимает 'int'. – szczurcio

3

Если вы не можете использовать std::vector, то вариант состоит в динамическом выделить массив указателей, затем динамически распределить n объектов и назначить полученную память указателям в массиве. Например:

constexpr auto ARRAYSIZE = 5; 

auto x = new PointPtr[ARRAYSIZE]; // should check for memory alloc errors 
for (int i = 0; i < ARRAYSIZE; ++i) 
{ 
    x[i] = new Point(5); // pass any arguments you want, remember to check if allocation was successful 
} 

Обратите внимание, что такая практика неодобрением, потому что вы не должны действительно не использовать new, если у вас есть очень веские причины, чтобы сделать это (и IMO, это глупо, что вы не позволили сделать вещи правильный путь и с самого начала преподавал хорошие практики); вместо этого используйте std::vector и интеллектуальные указатели, они должны быть в состоянии удовлетворить все ваши потребности в динамической памяти.

+0

Да, спасибо. Пожалуйста, прочитайте edit –

2

Примечание 1: Используя стандартную библиотеку (а именно std::vector в данном случае), чтобы обращаться с вещами, это prefereable!

Примечание 2: Лично я бы не пошел по массиву указателей, потому что вы уничтожаете свою память.

Вы можете использовать std::allocator:

// Create allocator object 
std::allocator<Point> alloc; 
// allocate storage for k Points 
Point * p = alloc.allocate(k); 
// Construct k Points in p 
for (std::size_t i{0}; i<k; ++i) 
{ 
    alloc.construct(p+i, 5); 
} 
// Do stuff using p 
// ... 
// Destroy k objects in p 
for (std::size_t i{0}; i<k; ++i) 
{ 
    alloc.destroy(p+i); 
} 
// Dealloacte memory 
alloc.deallocate(p, k); 

или вы можете обрабатывать ее вручную

// allocate 
Point * p = static_cast<Point*>(::operator new[](k*sizeof(Point))); 
// placement new construction 
for (std::size_t i{0}; i<k; ++i) 
{ 
    new((void *)(p+i)) Point{5}; 
} 
// stuff 
// destruction 
for (std::size_t i{0}; i<k; ++i) 
{ 
    (p+i)->~Point(); 
} 
// deallocation 
::operator delete[](static_cast<void*>(p)); 

где я обернуть обработку в функции памяти (если не класс) по крайней мере, :

#include <new> 
#include <utility> 
#include <cstddef> 

template<class T, class ... Args> 
T * new_n(std::size_t const n, Args&& ... args) 
{ 
    T * p{ (T*)::operator new[](n*sizeof(T)) }; 
    for (std::size_t i{ 0 }; i < n; ++i) 
    { 
    new((void*)(p + i)) T(std::forward<Args>(args)...); 
    } 
    return p; 
} 

template<class T> 
void remove_n(T * const p, std::size_t const n) 
{ 
    for (std::size_t i{ 0 }; i < n; ++i) (p + i)->~T(); 
    ::operator delete[]((void*)p); 
} 

и их использование

auto p = new_n<Point>(k, 5); 
// stuff using k Points in p constructed by passing 5 to constructors 
remove_n(p, k); 
+0

Итак, как я уже сказал в другом комментарии, я не могу использовать STL для этого задания. Я могу использовать его для другого, но я должен представить только указатели для этого задания. Спасибо, в любом случае! –

+0

'std :: size_t i {0}' - это, безусловно, самый оригинальный способ инициализации переменной цикла, которую я видел: P – szczurcio

+0

'std :: size_t i {}' также будет достаточным, не так ли? Я знаю, что C не разрешает пустые фигурные скобки, но у меня создалось впечатление, что C++. – dreamlax

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