Move Constructor doesn't get called

Hello guys.

I've my own class String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Move Constructor
GString(GString&& move)
{
    std::cout << "Move" << std::endl;
    
    // ... code ...
}

// Should invoke the Move Constructor
GString ToUpper()
{
	GString result{ *this };

	for (int i{ 0 }; i < size; ++i)
	{
		result[i] = toupper(mainString[i]);
	}

	return result;
}


1
2
3
4
5
6
7
8
9
int main()
{
 GString my{ "hello" };
 GString myupper{ my.ToUpper() };

 cout << myupper;

 return 0;
}


When I create myupper, I want the ToUpper() function to MOVE the value of my into myupper

I notice that my Move Constructor doesn't get called in this case, but the function just creates a COPY (exactly what I don't want) of the whole GString object.

I've heard about creating the Move Assignment also.
But it's strange because this I've written with the GString class works fine with my GList class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GList(GList&& move)
{
	std::cout << "Move constructor" << std::endl;

	// ... code ...
}

GList<T> Reverse()
{
        GList<T> result;

	// ... code ...

	return result;
}


In the main, if I do

1
2
3
4
GList<int> my(9);
my.push_head(8);

GList<int> my2(my.Reverse());


The output shows "Move Constructor", just like the cout I wrote in the GList Move Constructor.

I've done the SAME thing with the GString class... but it won't work!

Any tip?
Last edited on
Note:

The copy constructor gets called instead.

Why is it covering the move constructor?
http://en.cppreference.com/w/cpp/language/copy_elision

Your copy constructor isn't being called either.
Oh yeah I already read that documentation.

Still can't find out the issue...

Your copy constructor isn't being called either.


What do you mean by that?
The copy constructor is called, I put a cout

Screenshot: http://prntscr.com/a527an
Last edited on
cire wrote:
Your copy constructor isn't being called either.
gedamial wrote:
What do you mean by that?
The copy constructor is called, I put a cout

Perhaps I should be more specific. Neither your copy constructor nor move constructor are called for the return.

Yes, the copy constructor is used inside the function when you make a copy of *this. Line 12 in the first code snippet.
So yeah I'm using the copy constructor inside the function.

But when I return, how do I move instead of copying?
How do I call the copy constructor?
Last edited on
But when I return, how do I move instead of copying?

You just return. You're getting a more efficient strategy than moving or copying with copy elision. However, if for some reason you feel like you want to force a less efficient strategy, then use std::move in your return statement.
You just return


Why then in the second example (GList), the move constructor gets invoked?

What's the rule here? When does it / doesn't it get called?
What's the rule here? When does it / doesn't it get called?

There isn't a hard and fast rule (except as to when it can't happen.) I suppose the rule is to return and let the compiler sort out the most efficient way to do things. ;)

My guess would be that the difference you observed is in the compiler optimization settings. If you're using VC++, it typically forgoes copy elision in the default debug configuration.
I read from Bjarne Stroustrup book that when returning a large class object I should use a Move operation instead of a COPY (for obvious reasons)
So yeah, let's pretend GString is a very huge class.
I would NEVER want my computer to make a COPY of that object, so I define a Move Constructor... that doesnt get invoked lol

I dont understand the reason of this. It should perform a Move instead of a copy since I explicitly defined a Move Constructor
It should perform a Move instead of a copy since I explicitly defined a Move Constructor

A copy is not performed. You say you've visited the link I posted earlier, but you speak as if you haven't.
WHY does the GList move constructor get called then?
Is it racism? Lol
Last edited on
Topic archived. No new replies allowed.