Here is example class, the commented code in constructor works as well as the initializer.
My question is, what is the correct way?

class NClass
{
    public:

        int _pid;
        std::wstring _name;

        NClass(int pid, wchar_t * name) : _name(name)
        {
            //_name = name;

        }

        void Print()
        {
            std::wcout << _name;
            std::getchar();
        }

};

Perhaps it's another way like a copy or something, I've not used C++ for some time.

Thanks for looking in.

Edited 4 Months Ago by Suzie999

My question is, what is the correct way?

Are you concerned about shallow versus deep copy? If so, don't be. C++ strings do deep copies or at least lazy copies (which you are not responsible for), so you don't need to be worried about shallow copies Both of your initial methods seem equally correct. A compiler person might comment about the "under the hood" stuff and whether one might be more efficient than the other and under what circumstances. If you're unfamiliar with lazy copying, it's when the initial copy is shallow to save time, but something behind the scense keeps track of it, then when one of the objects mutates or is deleted, before that happens, the deep copy occurs. The overall lesson is you don't need to worry about it because it takes place behind the scene like Java's garbage collection. If you have a performance issue and long strings, you can experiment with the different ways and see what's fastest. But UNTIL then, I would not worry about it.

Your last one though seems like it might be unnecessarily inefficient regardless, though again I'm not a compiler guy. It might optimize the following problem away. The first two options seem like they would require one deep copy of name to _name. THIS one...

_name = std::wstring(name);

seems like it will create a new temporary wstring object requiring a deep copy from name to the temporary object for the std::wstring(name) part, THEN another deep copy of this new temporary object over to the _name variable for the assignment operator, THEN the destruction of the temporary object as it goes out of scope.

So that's two deep copies instead of one, plus some memory allocation taks that the other two ways don't need, unless the compiler is smart enough to optimize.

In all three cases, after you are done with the call to the constructor, you should have the same characters in both _name and name and they are stored separately so you can destroy one without messing up the other one. For a string like "Hello World", I don't imagine you'll see the slightest difference.

Thanks for detailed reply, especially regarding a possible double deep copy, I could really do without that as effifiency is critical in what will be a really tight loop.

My concern was that the parameter that is passed to the constructor will definately be destroyed, or at least the contents at the address will be changed almost immediately after the class creation.

My concern was that the parameter that is passed to the constructor will definately be destroyed, or at least the contents at the address will be changed almost immediately after the class creation.

I wouldn't worry about that. Just did a little experiment changing the name string immediately after calling the constructor and before calling the Print function. All three ways printed fine. My guess is that an immediate deep copy happens in the constructor.

Looking at the disassembly, it APPEARS that using the assignment operator might result in a few extra function calls as opposed to your original initialization from your first post with the assignment operation commented out, so using the assignment operator might be a TAD slower, but I'm thinking fairly negligible. YMMV. Again, key word would be "appears" since I'm not that good at reading the disassembly.

Thanks, AssertNull, that's good enough for me. I appreciate you taking the time to look into it.
May your days be merry.

This question has already been answered. Start a new discussion instead.