In C++11 we are guided in some cases to pass objects by value and in others by const-reference. However, this guideline depends on the implementation of the method, not just on its interface and intended usage by its clients.
When I write an interface, I do not know how it will be implemented. Is there a good rule of thumb for writing method signatures? For example - in the following code fragment, should I use Bar1
or Bar2
?
class IFoo
{
public:
virtual void Bar1(std::string s) = 0;
virtual void Bar2(const std::string& s) = 0;
};
You can stop reading here if you agree that the correct signature depends on the implementation. Here is an example that shows why I believe so.
In the following example, we should pass the string by value:
class Foo
{
std::string bar;
Foo(std::string byValue)
: bar(std::move(byValue))
{
}
};
Now we can instantiate Foo in an efficient manner in all cases:
Foo foo1("Hello world"); // create once, move once
Foo foo2(s); // the programmer wants to copy s. One copy and one move
Foo foo3(std::move(t)); // the programmer does not need t anymore. No copy at all
In other cases we prefer to pass objects by const reference. For example, in the following case we never want to copy/store the argument, just use its methods:
void DoStuff(const std::string& byRef)
{
std::cout << byRef.length() << std::endl;
}
All possible usages of the above method are already as efficient as possible.
Update
I believe I forgot to show the issues with the const-reference alternative. If the above class Foo
was implemented this way:
class Foo
{
std::string bar;
Foo(const std::string& byRef)
: bar(byRef)
{
}
};
Then we would have the following results:
Foo foo1("Hello world"); // Here we would have one more copy of the string. It is less efficient.
Foo foo2(s); // One copy, like before
Foo foo3(std::move(t)); // Irrelevant here.
Alex.
Foo foo("Hello world")
would cause the string to be copied twice if it was passed by const-reference (once during construction of the string and once inside the constructor of Foo when the string is copied). – Plagio