Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Type t = Type() call the copy constructor?

I'm really confused.... does Type t = Type() call the copy constructor or no?

I'm asking because when I try:

#include <iostream>

class Test
{
public:
    Test(Test const &) { std::cout << "hello"; }
    Test() { }
};

int main()
{
    Test t = Test();
    return 0;
}

nothing is output, but when I change it to

#include <iostream>

class Test
{
    Test(Test const &) { std::cout << "hello"; }
public:
    Test() { }
};

int main()
{
    Test t = Test();
    return 0;
}

I get:

error C2248: 'Test::Test' : cannot access private member declared in class 'Test'

which doesn't make sense (especially since this is a debug build).

Update:

Even this compiles!

struct Test
{
    Test(Test &&) = delete;
    Test(Test const &) = delete;
    Test() { }
};

int main()
{
    Test t = Test();
    return 0;
}

So is a copy/move constructor necessary or no?

like image 895
user541686 Avatar asked Oct 21 '22 20:10

user541686


1 Answers

From wikipedia:

In C++ computer programming, copy elision refers to a compiler optimization technique that eliminates unnecessary copying of objects. The C++ language standard generally allows implementations to perform any optimization, provided the resulting program's observable behavior is the same as if, i.e. pretending, the program was executed exactly as mandated by the standard.

The standard also describes a few situations where copying can be eliminated even if this would alter the program's behavior, the most common being the return value optimization. Another widely implemented optimization, described in the C++ standard, is when a temporary object of class type is copied to an object of the same type.[1] As a result, copy-initialization is usually equivalent to direct-initialization in terms of performance, but not in semantics; copy-initialization still requires an accessible copy constructor.[2] The optimization can not be applied to a temporary object that has been bound to a reference.

You are doing a copy construction, but the standard allows it to be converted to a direct initialization, and that is being done regardless of debug turned off, that's why the print isnt reached..

But, because it "should" be a copy construction, you do need access to one, which is why the second code doesnt work.

like image 125
RichardPlunkett Avatar answered Oct 27 '22 10:10

RichardPlunkett