calling non-default constructor with new[]

M

mati-006

Hi
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?
Now I have something like this:

p = new MyType[n];
for(int i=0;i<n;i++) p.init(val1,val2);

And this is ugly to me...
 
V

Victor Bazarov

mati-006 said:
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?

No, there is no way.
Now I have something like this:

p = new MyType[n];
for(int i=0;i<n;i++) p.init(val1,val2);

And this is ugly to me...


I have a pseudo-solution. It's not very nice, but it should work.

class MyType {
static ValType1 arg1;
static ValType2 arg2;
public:
static void setDefCtorArgs(ValType1 a1, ValType2 a2)
{
arg1 = a1; arg2 = a2;
}

MyType(ValType1 a1 = arg1, ValType2 = arg2); // "default"
};

...
MyType::setDefCtorArgs(val1, val2);
p = new MyType[n];

Don't foget to define 'MyType::arg1' and 'MyType::arg2' somewhere.

V
 
A

Alf P. Steinbach

* mati-006:
Hi
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?

If MyType is copyable you can use std::vector, like

Now I have something like this:

p = new MyType[n];
for(int i=0;i<n;i++) p.init(val1,val2);

And this is ugly to me...


Yes.
 
A

Andrey Tarasevich

mati-006 said:
...
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?

No. Meaning that there is no syntax that would 'new'-allocate an array and
invoke non-default constructors for its elements.
Now I have something like this:

p = new MyType[n];
for(int i=0;i<n;i++) p.init(val1,val2);

And this is ugly to me...


You can also do

p = new MyType[n];
std::fill_n(p, n, MyType(val1, val2));

assuming that your type's copy assignment operator is implemented appropriately.
 
F

Frederick Gotham

Victor Bazarov posted:
mati-006 said:
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?

No, there is no way.



Which begs the question. . .

Will this be fixed in the next Standard?
 
V

Victor Bazarov

Frederick said:
Victor Bazarov posted:
mati-006 said:
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?

No, there is no way.



Which begs the question. . .

Will this be fixed in the next Standard?

I doubt it. Arrays need to be revamped significantly and a patch
like that isn't worth the trouble. But do ask in 'comp.std.c++' or
look for proposals in the WG21 documents (the WB21 committee site
is http://www.open-std.org/jtc1/sc22/wg21/)

V
 
F

Frank Puck

mati-006 said:
Hi
Short question for which I can't find answer:
I want to initialize the array of objects with the same values.

new MyType[n]; calls default constructor
new MyType(val1, val2); initializes only one element

Is there any way to merge these two things?
Now I have something like this:

p = new MyType[n];
for(int i=0;i<n;i++) p.init(val1,val2);

And this is ugly to me...



maybe what you want is this:

std::vector<SmartPtr<MyType> > sVector(32);


for (unsigned int i = 0, iMax = sVector.size(); i < iMax; i++)
sVector = MyType::CreateElement(val1, val2);


template<class T>
class SmartPtr
{ private:
T *m_p;
public:
SmartPtr(void)
:m_p(0)
{
}
SmartPtr(T *_p)
:m_p(_p)
{ if (m_p)
m_p->AddRef();
}
SmartPtr(const SmartPtr<T> &_r)
:m_p(_r.m_p)
{ if (m_p)
m_p->AddRef();
}
~SmartPtr(void)
{ if (m_p)
m_p->Release();
}
operator=(const SmartPtr &_r)
{ if (m_p)
m_p->Release();
if (m_p = _r.m_p)
m_p->AddRef();
return *this;
}
operator T *(void) const
{ return m_p;
}
};

class MyType
{ private:
mutable unsigned int m_iRefCount;
double m_dVal1, m_dVal2;
MyType(void)
:m_iRefCount(0)
{
};
MyType(double _dVal1, double _dVal2)
:m_iRefCount(0),
m_dVal1(_dVal1),
m_dVal2(_dVal2)
{
}
virtual ~MyType(void)
{ assert(!m_iRefCount);
}
public:
void AddRef(void) const
{ m_iRefCount++;
}
void Release(void) const
{ assert(m_iRefCount);
--_iRefCount;
if (!m_iRefCount)
delete this;
}
SmartPtr<MyType> CreateElement(double _dVal1, double _dVal2)
{ return new MyType(_dVal1, _dVal2);
}
};



The class SmartPtr is a general class.
The methods AddRef() and Release() could be part of a general base class
(the destructor should be virtual).
Of course

std::vector<MyType*> sVector(32);

would also work -- but in this case I would rather write a derived class
from std::vector which cleans up the pointers inside the destructor, e.g.

template<class T>
class PtrVector:public std::vector<T>
{ public:
PtrVector(unsigned int _iSize = 0)
:std::vector(_iSize)
{
}
~PtrVector(void)
{ for (unsigned int i = 0, iMax = size(); i < iMax; i++)
delete (*this);
}
};
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top