1

I couldn't find the answer so I'm asking it here. What's the difference between THIS:

class Foo
{
public:
    Foo(std::string string)
        : m_String(std::move(string)) {}

private:
    std::string m_String;
}

And THAT:

class Bar
{
public:
    Bar(const std::string& string)
        : m_String(string) {}

private:
    std::string m_String;
}

I know that using a constructor from Bar copies data exactly from the value, but I don't really know what exactly happens when calling the Foo constructor. Is there a difference in using constructor from Foo or Bar?

1 Answers1

5

Don't use strings but a type where you can observe copying and moving:

#include <iostream>

struct test {
    test() { std::cout << "constructor\n"; }
    test(const test&) { std::cout << "copy\n";}
    test(test&&) { std::cout << "move\n"; }
};

class Foo {
public:
    Foo(test t) : t(std::move(t)) {}    
private:
    test t;
};

class Bar {
public:
    Bar(const test& t) : t(t) {}   
private:
    test t;
};

int main() {
    test t1;
    Foo f{t1};
    std::cout << "...........\n";
    test t2;
    Bar b{t2};
}

Output:

constructor
copy
move
...........
constructor
copy

Calling Foos constructor copies t1 to the constructors parameter, because it is taken by value and then the member is move constructed from the parameter.

Calling Bars constructor takes a reference (no copy, no move) and uses that to copy construct the member.


If the intention was to avoid the copying, you would provide a constructor that takes a test&&:

struct Baz {
    Baz(test&& t) : t(std::move(t)) {}
    test t;
};

Then Baz z(test{}); will construct a test and the member will be move constructed from that temporary. No copies involved.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • I know it's a bit different topic, but maybe could you shortly explain why `Foo f{t1};` was called with curly braces and the Bar with "typical" `()`? I read about it milion times but still can't get it – Robert Kwiatkowski May 29 '21 at 11:41
  • I totally forgot I can create a class which on certain constructor will tell me what happened. Thanks very much for explanation. – Miłosz Brzechczyn May 29 '21 at 13:04
  • @RobertKwiatkowski [Explanation about curly braces](https://stackoverflow.com/questions/18222926/why-is-list-initialization-using-curly-braces-better-than-the-alternatives) – Miłosz Brzechczyn May 29 '21 at 13:08
  • @RobertKwiatkowski the reason I used `()` for `Bar` was just carelessness. There is no huge difference in this example and here it is basically a matter of style. I am using `{}` here to be consistent with other cases where it does make a difference – 463035818_is_not_an_ai May 29 '21 at 13:31