Solved

C++ are std::wstrings passed by reference or is a copy made?

Posted on 2014-01-27
8
1,266 Views
Last Modified: 2014-01-30
Are std::wstrings passed by reference or is a copy made?
MyFunc(std::wstring s)
{
}

Open in new window

Am I receiving a copy of the string, or a pointer to the original string.
0
Comment
Question by:deleyd
8 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 39814044
In your example, you are indeed passing a copy of the string by value. When calling 'MyFunc()', the compiler generates code that copies the contents of 's' to the calling function's stack into a new 'wstring' instance. If you want to pass a reference, use '&', e.g.

MyFunc(std::wstring& s) // pass a reference instead
{
}
                                  

Open in new window


That does not only apply to 'wstring', but to all variables you could possibly pass.
0
 
LVL 24

Expert Comment

by:chaau
ID: 39814045
With your implementation you will get a copy of the string. If you change the code to this:
MyFunc(std::wstring &s)
{
}

Open in new window

you'll get a reference. On a side note, MFC CString has a built-in smartness to automatically pass strings by reference when using the code similar to yours:
MyFunc(CString s) // no copy will be made, equivalent to "const CString &s"
{
}

Open in new window

0
 
LVL 86

Expert Comment

by:jkr
ID: 39814046
Just to make that clear: You are responsible to decide whether a variable is passed by reference or value. The compiler will make no asumptions about that.
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 75 total points
ID: 39814265
to add to above comments:

std::wstring is typedef of template class std::basic_string<wchar_t>. basic_string internally uses reference counting for its internal string object (like most other string classes as well). that means if you make a copy of the wstring - like in your code - the new wstring object uses the same pointer as the original wstring and only the reference counter associated with the internal string object was incremented. the advantage of this technique is that copying strings don't add a penalty to the performance.

but, as these pointers were handled by the string class automatically, you don't have to care for.

MFC CString has a built-in smartness to automatically pass strings by reference when using the code similar to yours
CString also uses reference counting. but the CString object was a really copy which 'copied' the internal pointer member to the internal string object. so, it actually doesn't turn arguments from 'by value' to 'by reference', at least not in a technically manner.  

Sara
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 22

Assisted Solution

by:ambience
ambience earned 25 total points
ID: 39815098
It may be copied or moved - depends on the call-site. I've created a tiny example to explain the point. Replace A by wstring and the same semantics apply. In the case of wstring (since it is provided by STL) it is safe to assume that move semantics are available when you invoke std::move.


class A
{
public:
      A() {
            std::cout << "Default constructor" << std::endl;
      }
      A(const A& a) {
            std::cout << "Copy constructor" << std::endl;
      }
      A(A&& a) {
            std::cout << "Move constructor" << std::endl;
      }
};

class B
{
public:
         // Is 'a' copied in the traditional sense of copy? Maybe - Maybe not
      B(A a) {
      }
};

int main() {
      A a;
      B b1(a);                        
      B b2(std::move(a));  ---> Move Constructor/No Copy
}

-----------------
Output:
Default constructor
Copy constructor
Move constructor
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 75 total points
ID: 39815322
It may be copied or moved - depends on the call-site

when adding an A& member to B and output the A address you see that the A passed via std::move has a new address, same as with copy constructor. in neither case, the original A object was passed by reference.

class A
{
public:
      A() {
            std::cout << "Default constructor " << this << std::endl;
      }
      A(const A& a) {
            std::cout << "Copy constructor " << this << std::endl;
      }
      A(A&& a) {
            std::cout << "Move constructor " << this << std::endl;
      }
};

class B
{
    A & mya;
public:
         // Is 'a' copied in the traditional sense of copy? Maybe - Maybe not
      B(A a) : mya(a) {
      }
};

int main() { 
      A a;
      std::cout << "main &a " << &a << std::endl;
      B b1(a);                        
      B b2(std::move(a));  // ---> Move Constructor/No Copy
      return 0;
}

output:
----------

Default constructor 0037FE4F
main &a 0037FE4F
Copy constructor 0037FD48
Move constructor 0037FD48

Open in new window



Sara
0
 

Author Comment

by:deleyd
ID: 39816339
What is A& and A&& ?
0
 
LVL 32

Accepted Solution

by:
sarabande earned 75 total points
ID: 39817143
A& is passing A by reference.

A& is a c++ reference type referencing to an object of class A by 'address'. different to a pointer it is not a second variable but a reference (alias) to a the original A object, for example when passed as argument by the caller.

A&& is the new (pre-C++11 and C++11)  'move' value_type which describes a so-called 'xvalue' (opposed to value types 'lvalue' and 'rvalue', which describe at which side -left or right - of an assignment the variable can be used).

Only the following expressions are xvalues:
- A function call expression, if the function's return type is an rvalue reference
  to object type, such as std::move(val)
- A cast expression to an rvalue reference to object type, such as static_cast<T&&>(val)
  or (T&&)val
- a non-static class member access expression, in which the object expression
  is an xvalue
- A pointer-to-member expression in which the first operand is an xvalue and
  the second operand is a pointer to data member.


the xvalue is a value category used for moving objects in containers. if for example elements were sorted in a std::vector you of course would not create (deep) copies of each pair of elements that were swapped. so a 'move' object normally is a 'flat' copy of the original object (beside the 'move' constructor would make a difference) for temporary use. it is writeable but different to a pure reference it would not change the original object as it has a new address and is a separate object.

as ambience has shown the T&& type allows to define new overrides of constructors and functions which could implement a special handling for those xvalues.

see http://en.cppreference.com/w/cpp/language/value_category for details

Sara
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
maze travler 6 47
QAction use more than one time. 3 20
Exception thrown at 0x00007FFD5BC81F28 7 31
Problem with SqlConnection 5 121
Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now