Problem with array of objects initialization with non-default constructor

Hello,

I want to build array of some simple class as in topic. I use brace notation similar to agregates. I know that the class with non-default user's constructor is not agregate. The problem seems to me more complicated...
The code is :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class typ2
{
    int rightd, leftd;

    public:
    typ2(int arg1 = 0, int arg2 = 0): rightd(arg1), leftd(arg2)
    {
        cout << "In cstr2... leftd: " << leftd << " rightd: " <<rightd << endl;
    }
 //   typ2(typ2& objsrc)
 //   {
 //       this->rightd = objsrc.leftd;
 //       this->leftd  = objsrc.rightd;
 //       cout << "In cstr COPY typ2" << endl;
 //   }


};


int main()
{
    cout << "In main" << endl;
    typ2 obj;

    typ2 tab[3] = {typ2(1,2),typ2(2,1),typ2(1,5)};

    return 0;
}


As we see I use explicit initialization with constructor that also works without arguments. That code works fine at this stage. I assume that compiler create temporary object on stack with default cstr and then invoke copy constructor to copy objects like memberwise behaviour.
Is that correct assumption? Please verify. Nevertheless later if I define (or uncomment) copy constructor then code does not compile.

Compiler reports:
error: no matching function for call to 'typ2::typ2(typ2)'|
|note: candidates are: typ2::typ2(typ2&)|

But I have been already defined that copy constructor which compiler doesn't use.

Why compiler simply not invoke my new copy constructor instead default copy cstr?
Is there any restriction due to cpp brace syntax in that case?
What solution to alternatively define array of initialized objects ?
Last edited on
As you rightly said, the compiler creates temporary objects. Since temporary objects are always const, your copy constructor should be typ2(const typ2& objsrc)
But I have been already defined that copy constructor which compiler doesn't use.
No you don't. You defined a constructor which takes mutable reference to your class. That is not a copy constructor.
Copy constructor should have folllowing signature: foo::foo(const foo&)

I assume that compiler create temporary object on stack with default cstr and then invoke copy constructor to copy objects like memberwise behaviour.
Actually compiler will try to move temporary objects in place, but you did not define move constructor nor it is possibly to generate it, so it will fall back to copy. (and for your class it is impossible to write move constructor more effective than copy one).
With the advent of uniform initialization you can do: typ2 tab[3] = {{1,2},{2,1},{1,5}}; and this will be more effective as it will construct elements in place instead of moving/copying them.

I suggest you to initialize your object in copy constructor using constructor init list, as you did with parametrized constructor.
Last edited on
Topic archived. No new replies allowed.