Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Array of objects from class without default constructor

2 views
Skip to first unread message

Matthias

unread,
Mar 30, 2009, 9:00:15 AM3/30/09
to
Hi,

As far as I know, it's not possible to get an array new-expression
call a class constructor with parameters. Thus, it is non trivial
to build an array of object belonging to a class, say A, without
default constructor.

To bypass this limitation, one can add a trivial constructor to
class A. The resuting code looks like the following:

class A {
public:
A() {};
A(const size_t & n) { ... };
}

const size_t m = 5;
const size_t n = 10;
A * t;

t = new A [n];
for (size_t i = 0; i < n; ++i)
t[i] = A(m);

I don't feel confortable with this solution: from my program
design it's non-sense to build an A object without specifying its
size...

Are there other solutions to the `array of objects from class
without default constructor' problem? Does my solution looks
horrible to C++ aesthetes?

Thanks for reading!
--
Matthias

Vladyslav Lazarenko

unread,
Mar 30, 2009, 9:36:27 AM3/30/09
to
On Mar 30, 9:00 am, Matthias <oron...@gmail.com> wrote:
>
> Are there other solutions to the `array of objects from class
> without default constructor' problem?
>

I would allocate raw memory without any specific class first, then
call "placement new" operator with non-default constructors.

>
> Does my solution looks
> horrible to C++ aesthetes?
>

It is not horrible but you have unnecessary copying.

P. Lepin

unread,
Mar 30, 2009, 10:14:43 AM3/30/09
to

Matthias wrote:
> As far as I know, it's not possible to get an array new-expression call
> a class constructor with parameters. Thus, it is non trivial to build an
> array of object belonging to a class, say A, without default constructor.
>
> To bypass this limitation, one can add a trivial constructor to class
> A. The resuting code looks like the following:

[code]

> I don't feel confortable with this solution: from my program design it's
> non-sense to build an A object without specifying its size...
> Are there other solutions to the `array of objects from class without
> default constructor' problem? Does my solution looks horrible to C++
> aesthetes?

(not a C++ expert, take everything below with a biiig grain of
salt)

Well, you could always decide to over-engineer and do something
like this (assuming you have control over the class interface):

#include <iostream>
#include <ostream>
class NextSizeCallback {
public: virtual int operator()() = 0; };
class IncCallback: public NextSizeCallback {
public: IncCallback(): n_(1) { }
virtual int operator()() { return n_++; }
private: int n_; };
class A {
public: static void setNextSizeCallback(
NextSizeCallback* c) { A::c_ = c; }
static int getNextSize() { return (*A::c_)(); }
A(): n_(getNextSize()) { }
int getSize() const { return n_; }
private: static NextSizeCallback* c_;
int n_; };
NextSizeCallback* A::c_ = NULL;
int main() {
IncCallback i;
A::setNextSizeCallback(&i);
A* t = new A[10];
for (int i = 0; i != 10; ++i)
std::cout << t[i].getSize() << std::endl;
return 0; }

I doubt this is any better in terms of readability and
maintainability than using placement new and creating your
objects explicitly, though.

--
Waterfall: One Process To Rule Them All

SG

unread,
Mar 30, 2009, 10:27:06 AM3/30/09
to
On 30 Mrz., 15:00, Matthias <oron...@gmail.com> wrote:
> As far as I know, it's not possible to get an array new-expression
> call a class constructor with parameters. Thus, it is non trivial
> to build an array of object belonging to a class, say A, without
> default constructor.
> [...]

> Are there other solutions to the `array of objects from class
> without default constructor' problem?

Use a std::vector<A> and its push_back function. A vector's value
type only needs to be copy-constructible. push_back will copy-
construct the new element in the vector.

Altough this is not of help for you now it's IMHO still worth
mentioning: The future C++ version will replace the "copy
constructible" requirement with a "move constructible" requirement for
the value type. Also, it will be possible to directly create such an
object in the vector via std::vector::emplace_back à la

std::vector<A> avec;
avec.emplace_back(5);


Side note: Consider making A::A(size_t) an explicit constructor.


Cheers!
SG

Juha Nieminen

unread,
Mar 30, 2009, 10:31:48 AM3/30/09
to
Matthias wrote:
> As far as I know, it's not possible to get an array new-expression call
> a class constructor with parameters. Thus, it is non trivial to build an
> array of object belonging to a class, say A, without default constructor.

It may not be trivial, but it isn't very hard either. STL data
containers use this kind of technique all the time. (How do you think
their reserve() function works?)

What you do is that instead of using new, you allocate space using
::operator new (which does not initialize the allocated memory and
returns a void*), and then you initialize this allocated memory with
placement new. This is a bit low-level programming (and slightly
error-prone), but not very difficult.

Matthias

unread,
Mar 31, 2009, 6:15:56 AM3/31/09
to
Thank you for your answers, and suggestions!

I've finaly decided to pre-allocate storage without initialization
(a call to ::operator new, followed by static_cast) then
initialize individual elements with a placement new.

Yes, Juha, this wasn't difficult! The syntax is not easily found,
but the result is quite readable.

Thanks a lot!
--
Matthias

0 new messages