std::string in struct - Copy/assignment issues?
Asked Answered
J

4

7

Suppose I have a struct containing a std::string, like this:

struct userdata{
        int uid;
        std::string username;
    }

Do I need to create a copy ctor or anything to return it from a function or to use it inside a STL container? Consider this function:

userdata SomeClass::GetUserData(unsigned int uid)
{
    //do error checking and other stuff...
    //m_usermap is std::map<unsigned int, userdata>
    return m_usermap[uid];
}

When I insert userdata structs into the std::map, a copy of the struct gets created, right? Does a new std::string get created using the value of the username field, or does some sort of bitwise copy happen (this would be bad)? Similarly, when I return a userdata struct from the GetUserData method, does it have an independent string holding the username or do I need to define a copy ctor and explicitly create a new string?

Jetliner answered 5/1, 2010 at 23:42 Comment(3)
Remember that 'struct' and 'class' interchangeably define class-types, with the only difference being public or private default access. (It's a common misconception, even though you didn't directly say you believed this.) This means userdata has a copy ctor even though you didn't explicitly declare one (all class-types have a copy ctor), and the compiler-generated one will do a member-wise copy, which calls the copy ctor of each member, and that's how alemjerus's answer below applies. All compiler-generated copy ctors and assignment operators behave member-wisely instead of bit-dumbly.Werbel
When in doubt, write copy constructor and assignment operators for the struct or class. I prefer not to rely on hidden activities of the compiler.Romeyn
@Thomas: I completely disagree with that advice. The compiler generates ones do a perfectly good job. Unless you know what they are doing a novice is going to make a mistake, while somebody who does know what they are doing does not need to do anything. So unless the class contains a pointer the default methods are absolutely fine and probably better than a novice could write. Additionally less code means less maintenance costs.Inexorable
C
0

std::string is reference-counted, and its copy constructor takes place. So nothing to worry about. Everything is handled correctly.

Cambium answered 5/1, 2010 at 23:46 Comment(2)
It is not true that string is reference counting. Implementation can use or not use ref. counting.Wickman
While a few (mostly older) implementations of std::string are reference counted, most of the newer ones are not. Regardless of that, however, it must handle copy construction, copy assignment, etc., correctly, so outside code doesn't need to worry about it.Gazebo
M
11

You don't have to do anything special. C++ (and the implementation of STL) define this to just work.

Monomial answered 5/1, 2010 at 23:43 Comment(0)
C
4

std::strings by themselves can be copied without any problems.

When you define a class (or struct), C++ will generate a number of methods for you by default, including a copy constructor and an assignment operator. I believe that the generated copy constructor will call the copy constructor on each of fields, and the generated assignment operator will call the assignment operator on each of the fields. As your userdata struct is copied, std::string's copy constructor will be called for the username field.

The STL containers and algorithms should use some combination of the copy constructor and the assignment operator, so this should all be fine.

Czech answered 6/1, 2010 at 0:6 Comment(1)
Your believe is true, the generated constructors/assignment operator will use the available (or generated) versions in each of the member attributes. You only need to redefine them when you need to hold resources hold by a handler (i.e. a pointer for memory resources...) whose lifetime is controlled within your class.Chaetognath
I
2

As long as you don't have pointers as your datamembers, you should be fine.

Inherence answered 6/1, 2010 at 0:23 Comment(1)
It is better to generalize 'pointers' to 'handlers' into resources controlled by the class. In some cases you may hold resources that are not memory through other types of handlers.Chaetognath
C
0

std::string is reference-counted, and its copy constructor takes place. So nothing to worry about. Everything is handled correctly.

Cambium answered 5/1, 2010 at 23:46 Comment(2)
It is not true that string is reference counting. Implementation can use or not use ref. counting.Wickman
While a few (mostly older) implementations of std::string are reference counted, most of the newer ones are not. Regardless of that, however, it must handle copy construction, copy assignment, etc., correctly, so outside code doesn't need to worry about it.Gazebo

© 2022 - 2024 — McMap. All rights reserved.