0

I cant follow why i cant initialize my class object in one line like below. Getting VS errors which are not simple for me:

"error:E0334 class "example" has no suitable copy constructor"

and

"C2440 'initializing': cannot convert from 'example' to 'example'"

Some code:

class example {
public:
    example() { R = 0.F; I = 0.F; };
    example(float, float);
    example(example &);
    example sum( float, float);
private:
    float R, I;
};

example::example(float s1, float s2):R(s1), I(s2) {}

example::example(example & ex2) {
    R = ex2.R;
    I = ex2.I;
}

example example::sum(float s1, float s2){
    example s;
    s.R = s1;
    s.I = s2;
    return s;
}

int main() {
    float a = 2;
    float b = 4;
    example object1(1,1);
    example object2(object1.sum(a,b));
    return 0;
}

Why initializing object2 like this:

example object2(object1.sum(a,b));

getting error, but something like this:

example object2;
object2 = (object1.sum(a,b));

pass without error, is it ok?

Mat3o
  • 5
  • 1
  • 4

2 Answers2

1

You're missing a const in the copy constructor

example(example const &);

Why initializing object2 like this:

example object2(object1.sum(a,b));

getting error

Because you can't get a non-const reference from the rvalue object1.sum(a,b).

but something like this:

example object2;
object2(object1.sum(a,b));

is ok?

This code is also wrong, the second line would require an operator ().

O'Neil
  • 3,790
  • 4
  • 16
  • 30
  • 1
    [Do you always need a const in copy constructor?](https://timsong-cpp.github.io/cppwp/class.copy#ctor-1) – Joseph D. Jun 04 '18 at 01:12
  • Yep. A const isn't required for a copy c'tor, but is necessary for it to be able to catch an rvalue reference (rvalues can be bound to const-lvalue references). – iBug Jun 04 '18 at 01:50
  • Now, I get it, but in second I've mean: `object2 = (object1.sum(a,b));` with this compilator passes without error. – Mat3o Jun 04 '18 at 01:56
  • @Mat3o `object2 = (object1.sum(a,b));` does not call copy constructor but [copy assignment operator](http://en.cppreference.com/w/cpp/language/copy_assignment). – O'Neil Jun 04 '18 at 14:12
0
example object2(object1.sum(a,b));

this is not copy constructor, this is move constructor because argument is rvalue.

so, you can add move constructor explicitly like this.

class example {
public:
    example() { R = 0.F; I = 0.F; };
    example(float, float);
    example(example &);
    //move
    example(example &&);
    example sum( float, float);
private:
    float R, I;
};

example::example(float s1, float s2):R(s1), I(s2) {}

example::example(example & ex2) {
    R = ex2.R;
    I = ex2.I;
}

example::example(example && ex2){
    R = ex2.R;
    I = ex2.I;
}

example example::sum(float s1, float s2){
    example s;
    s.R = s1;
    s.I = s2;
    return s;
}

int main() {
    float a = 2;
    float b = 4;
    example object1(1,1);
    example object2(object1.sum(a,b));
    return 0;
}

and this

example object2;
object2 = (object1.sum(a,b));

is ok because,it will call copy assignment operator that compiler generate automatically (when you add move constructor like me, compiler will not generate copy assignment operator)

  • Is it good if i only change from `example(example &);` to `example(example const &);` in my code? – Mat3o Jun 04 '18 at 02:03
  • As my opinion, move constructor is better because example::sum make object temporary. If example::sum return self, example(const example &); is better. – Wasting Time Master Jun 04 '18 at 02:10