Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

copy constructor and move constructor

91 views
Skip to first unread message

Sui Huang

unread,
Sep 20, 2015, 9:15:51 AM9/20/15
to
Hi everyone, I got trouble with copy or move operations.

I wrote a class HasPtr when learning chapter 13 of <C++ Primer>.
/* header file */
class HasPtr{
public:
HasPtr(const std::string &str = std::string()) :
ps(new std::string(str)), val(0) {std::cout << "default constructor";}
HasPtr(const HasPtr &); //output "copy constructor"
HasPtr(HasPtr &&) noexcept; //output "move constructor"
HasPtr &operator=(const HasPtr &); //output "copy assignment"
HasPtr &operator=(HasPtr &&) noexcept; //output "move assignment"
~HasPtr();
private:
std::string *ps;
int val;
};

I have implemented HasPtr correctly, in each member function, print the function name. And I cann't understand these outputs that :
/* test code */
#1. HasPtr ptr = HasPtr(); //call "Default Constructor"
#2. HasPtr ptr2(HasPtr()); //outpus nothing
#3. vector<HasPtr> items = {HasPtr("abc"), HasPtr("def")}; //first call default constructor, then copy constructor

#1. I think right side object is rvalue, why not first call default then move constructor?
#2. I think this should work like #1.
#3. When copy objects to vector, why not call move constructor?

By the way, my compile environment is gcc 4.9.2 in Ubuntu 15.04

Öö Tiib

unread,
Sep 20, 2015, 11:13:46 AM9/20/15
to
On Sunday, 20 September 2015 16:15:51 UTC+3, Sui Huang wrote:
> Hi everyone, I got trouble with copy or move operations.

No. You got trouble with most vexing parse.
https://en.wikipedia.org/wiki/Most_vexing_parse

> #2. HasPtr ptr2(HasPtr()); //outpus nothing

There you declare a function.

mark

unread,
Sep 20, 2015, 1:37:17 PM9/20/15
to
On 2015-09-20 15:15, Sui Huang wrote:
> #3. vector<HasPtr> items = {HasPtr("abc"), HasPtr("def")}; //first call default constructor, then copy constructor
> [...]
> #3. When copy objects to vector, why not call move constructor?

Initializer lists don't support move, the elements can only be accessed
as const and thus must be copied.

There is a proposal to support move, so this may be possible in C++17.

Paavo Helde

unread,
Sep 20, 2015, 3:34:53 PM9/20/15
to
Sui Huang <hailiy...@gmail.com> wrote in
news:2eda2e20-0bad-4cde...@googlegroups.com:

> #1. HasPtr ptr = HasPtr(); //call "Default Constructor"
>
> #1. I think right side object is rvalue, why not first call default
> then move constructor?

Most probably the move constructor has been optimized away and the object
is constructed directly in the right place.

Others have already answered other questions.


Sui Huang

unread,
Sep 21, 2015, 3:54:14 AM9/21/15
to
在 2015年9月20日星期日 UTC+8下午11:13:46,Öö Tiib写道:
thanks, that is really a vexing parse.
It is really confusing that HasPtr() is parsed as a function returning type HasPtr.
whatever, I got it. thank you.

Sui Huang

unread,
Sep 21, 2015, 3:56:35 AM9/21/15
to
在 2015年9月21日星期一 UTC+8上午3:34:53,Paavo Helde写道:
So excepts copy elision, RVO as far as I know, are there many other compiler optimizations in C++?

Sui Huang

unread,
Sep 21, 2015, 3:59:42 AM9/21/15
to
在 2015年9月21日星期一 UTC+8上午1:37:17,mark写道:
thank you, I don't know much about initializer list. I just learn that it will excutes copy-initialization. Does copy-initialization either call copy constructor or move constructor?

Paavo Helde

unread,
Sep 21, 2015, 4:21:10 AM9/21/15
to
Sui Huang <hailiy...@gmail.com> wrote in
news:01090f77-d0ca-44c8...@googlegroups.com:
There are many optimizations, but AFAIK elision of copy and move
constructors are the only ones which are allowed to change observable
behavior in a valid portable C++ program. Basically this means the
program should not rely on if and when the copy and move constructors are
called.

If the program uses undefined, unspecified or implementation-specified
behavior, then of course one may see changes in the observable behavior
also elsewhere. A good example is optimizing away some code which is
breaking strict aliasing rules
(http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-
rule)

Cheers
Paavo

Öö Tiib

unread,
Sep 21, 2015, 11:21:18 AM9/21/15
to
AFAIK only clang does hint [-Wvexing-parse] that your code seems to
contain it. It is one of most obscure features of C++. Most programmers
keep function declarations in header files and static function declarations
in start of cpp file. Therefore it is surprising that most compilers tell nothing
about a function declaration in function body. It is allowed, but unusual so
worth a warning IMHO.

Richard

unread,
Sep 22, 2015, 1:21:05 PM9/22/15
to
[Please do not mail me a copy of your followup]

Sui Huang <hailiy...@gmail.com> spake the secret code
<d836ff05-1efe-4982...@googlegroups.com> thusly:

>在 2015年9月20日星期日 UTC+8下午11:13:46,Öö Tiib写道:
>> On Sunday, 20 September 2015 16:15:51 UTC+3, Sui Huang wrote:
>> > Hi everyone, I got trouble with copy or move operations.
>>
>> No. You got trouble with most vexing parse.
>> https://en.wikipedia.org/wiki/Most_vexing_parse
>>
>> > #2. HasPtr ptr2(HasPtr()); //outpus nothing
>>
>> There you declare a function.
>
>thanks, that is really a vexing parse.

C++11 brace initialization gives you what you want, so another reason
to prefer that for initializing a variable.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
0 new messages