Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass in constructor arguments with new

Tags:

c++

I'm trying to pass in arguments into a constructor but meanwhile making an array of objects like that. I used the following code to get there:

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

Well, that wasn't a syntax error, but it didn't compile. I didn't really want to hard-code "5" into a default constructor for Point. Got any ideas on how I should do this? Thanks!

BTW, I did typedef Point *PointPtr somewhere else already.

Sorry if the title wasn't accurate. I didn't know how to summarize this.

like image 851
Jack Thomas Avatar asked Nov 29 '15 23:11

Jack Thomas


People also ask

How do you pass parameters to a constructor?

You can only define the coursebookname variable one time (which is when you specify the type). Remove the String designation from before the variable name when you pass it to the Person constructor and it should work fine. Person p1 = new Person(cousebookname); Spelling aside.

How do you pass a parameter to a constructor in C++?

Parameterized Constructors: It is possible to pass arguments to constructors. Typically, these arguments help initialize an object when it is created. To create a parameterized constructor, simply add parameters to it the way you would to any other function.

How many arguments we can pass in constructor?

This method takes four arguments: the loan amount, the interest rate, the future value and the number of periods. The first three are double-precision floating point numbers, and the fourth is an integer.

Can a copy constructor have multiple arguments?

A copy constructor has one parameter that is a reference to the type that is copied. It can have additional parameters, if these have default values.


2 Answers

I would suggest using a std::vector:

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

But you can also do it as:

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

Live Demo

like image 156
101010 Avatar answered Oct 13 '22 02:10

101010


Note 1: Using the standard library (namely std::vector in this case) to handle things is prefereable!

Note 2: Personally, I wouldn't go down the array of pointers route because you destroy your memory locality.

You can use 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);

or you can handle it manually

// 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));

where I'd wrap the memory handling into functions (if not a class) at least:

#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);
}

and use them

auto p = new_n<Point>(k, 5);
// stuff using k Points in p constructed by passing 5 to constructors
remove_n(p, k);
like image 40
Pixelchemist Avatar answered Oct 13 '22 02:10

Pixelchemist