Is it the standard behaviour that the copy constructor is called when I
initialize an array of a class type?
And if so, is it possible to initialize an array of objects without invoking
the copy constructor?
My problem is that my class has a private copy constructor (and an explicit
constructor - but I do not know whether this is relevant).
Below is my sample code (which does not compile). How do I have to write the
definition of "D::c" so that it compiles without changing class C?
Thanks in advance!
Greets Chris
-----------------
class C
{
public:
explicit C(int i) : i_(i) {}
private:
C(const C&);
int i_;
};
class D
{
static C c[2];
};
C D::c[2] = { C(0), C(1) };
int main()
{
}
Yes, you're initializing your objects from temporaries. That requires a
callable copy c-tor.
> And if so, is it possible to initialize an array of objects without invoking
> the copy constructor?
Don't create temporaries. You could initialise those elements directly,
but not with an explicit c-tor.
> My problem is that my class has a private copy constructor (and an explicit
> constructor - but I do not know whether this is relevant).
> Below is my sample code (which does not compile). How do I have to write the
> definition of "D::c" so that it compiles without changing class C?
There is no way.
At first I was thinking you could leave it uninitialised, but that would
require a default c-tor, which you don't have. Adding it would mean
changing class C.
So, something's gotta give.
>
> Thanks in advance!
>
> Greets Chris
>
> -----------------
>
> class C
> {
> public:
> explicit C(int i) : i_(i) {}
> private:
> C(const C&);
> int i_;
> };
>
> class D
> {
> static C c[2];
> };
>
>
> C D::c[2] = { C(0), C(1) };
>
>
> int main()
> {
> }
>
>
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Victor Bazarov wrote:
> Christian Meier wrote:
>> Is it the standard behaviour that the copy constructor is called when I
>> initialize an array of a class type?
>
> Yes, you're initializing your objects from temporaries. That requires a
> callable copy c-tor.
>
>> And if so, is it possible to initialize an array of objects without
>> invoking the copy constructor?
>
> Don't create temporaries. You could initialise those elements directly,
> but not with an explicit c-tor.
>
How do I do that? If I remove the "exclicit" keyword in my sample code and
change the initializer-statement to "C D::c[2] = { 0, 1 };" then my compiler
still tries to call the copy constructor:
main.cpp:6: error: 'C::C(const C&)' is private
>> My problem is that my class has a private copy constructor (and an
>> explicit constructor - but I do not know whether this is relevant).
>> Below is my sample code (which does not compile). How do I have to write
>> the definition of "D::c" so that it compiles without changing class C?
>
> There is no way.
>
> At first I was thinking you could leave it uninitialised, but that would
> require a default c-tor, which you don't have. Adding it would mean
> changing class C.
>
> So, something's gotta give.
>
If I left it uninitialized then they would have the same value.
Hm... Maybe I'm wrong. I thought it would do direct initialization.
Lemme look it up... <opens the Standard>
8.5/12 says <<The initialization that occurs in argument passing,
function return, throwing an exception (15.1), handling
an exception (15.3), and brace-enclosed initializer lists (8.5.1) is
called copy-initialization ...>>
That's too bad (for your situation, I mean). I was wrong - the copy
c-tor still needs to be accessible even if the compiler doesn't need it.
It's the "as-if" rule.
>>> My problem is that my class has a private copy constructor (and an
>>> explicit constructor - but I do not know whether this is relevant).
>>> Below is my sample code (which does not compile). How do I have to write
>>> the definition of "D::c" so that it compiles without changing class C?
>> There is no way.
>>
>> At first I was thinking you could leave it uninitialised, but that would
>> require a default c-tor, which you don't have. Adding it would mean
>> changing class C.
>>
>> So, something's gotta give.
>>
>
> If I left it uninitialized then they would have the same value.
They can't be left uninitialised, your class has no default c-tor.
> >> So, something's gotta give.
> >>
> >
> > If I left it uninitialized then they would have the same value.
>
> They can't be left uninitialised, your class has no default c-tor.
If you do not want to lose the access level protection, you can only use a factory function: either a friend or a class member has to create the array and return a pointer to it. There is no other way (at least to my knowledge), due to the array initialisation limitations in C++.
Regards,
Robert
> Yes, you're initializing your objects from temporaries. That
> requires a callable copy c-tor.
> > And if so, is it possible to initialize an array of objects
> > without invoking the copy constructor?
> Don't create temporaries. You could initialise those elements
> directly, but not with an explicit c-tor.
> > My problem is that my class has a private copy constructor
> > (and an explicit constructor - but I do not know whether
> > this is relevant). Below is my sample code (which does not
> > compile). How do I have to write the definition of "D::c" so
> > that it compiles without changing class C?
> There is no way.
There is a way, but it's far from simple. The "array" must be
declared as an array of unsigned char, with the appropriate
size, and the appropriate precautions to ensure correct
alignment, and then you use placement new to initialize each
object in the array.
Not for the faint at heart.
--
James Kanze
<snip>
> 8.5/12 says <<The initialization that occurs in argument passing, function
> return, throwing an exception (15.1), handling
> an exception (15.3), and brace-enclosed initializer lists (8.5.1) is
> called copy-initialization ...>>
>
> That's too bad (for your situation, I mean). I was wrong - the copy c-tor
> still needs to be accessible even if the compiler doesn't need it. It's
> the "as-if" rule.
You're right, 8.5 / 12 is the explanation. Not only the "is called
copy-initialization" but also that "is equivalent to the form T x = a;".
It explains why I have to create temporaries when having an explicit
constructor (and an accessible copy constructor).
Thanks for your answers.
Greets Chris