1

As per "Inside C++ Object Model" a copy constructor is generated (if not declared by the programmer) by the compiler only when at least any one of the below four conditions are true:

  1. When the class contains a member object of a class for which a copy constructor exists (either explicitly declared by the class designer, as in the case of the previous String class, or synthesized by the compiler, as in the case of class Word)

  2. When the class is derived from a base class for which a copy constructor exists (again, either explicitly declared or synthesized)

  3. When the class declares one or more virtual functions

  4. When the class is derived from an inheritance chain in which one or more base classes are virtual

Which means if I have a class with just constructor then copy constructor will not be provided by the compiler.

Lets take an example:

class test
{
    test(){}
};
int main()
{
    test obj1;       //statement 1
    test obj2(obj1); //statement 2
}

Above code works fine. Now the problem comes when I add the following lines in class test:

test(const test& rhs) = delete;

"= delete" ensures that copy constructor is not automatically provided. After adding above line I am getting an error for statement 2 which says Use of deleted function test::test(const test&).

My question is: as per "Inside C++ Object Model" I don't need a copy constructor for the above class so when I am explicitly saying not to generate a copy constructor (using delete) why am I getting an error? Since I was expecting that the compiler won't need a copy constructor for the above class.

I am using gcc version 4.6.3.

pb2q
  • 58,613
  • 19
  • 146
  • 147
user1431221
  • 11
  • 1
  • 2
  • 1
    If a _copy-constructor_ wasn't provided then your statement 2 wouldn't compile. – K-ballo Jun 01 '12 at 17:44
  • It works fine if i dont add test(const test& rhs) in class. – user1431221 Jun 01 '12 at 17:46
  • statement 2 doesn't use a default constructor, it uses the copy constructor and if you declared it and deleted it (which you did), then it won't compile because statement 2 matches the deleted signature. – wkl Jun 01 '12 at 17:46
  • You should review the quote from the book, as the version you copied is incorrect. If the book really says this, then it is in error. – David Rodríguez - dribeas Jun 01 '12 at 18:21
  • If you're using a deleted constructor then you're using C++11 and I'm pretty sure no edition of that book covers C++11. The rules changed regarding when copy constructors are implicitly-defined. That said, the rules you quote look like the rules for a _non-trivial_ copy ctor in C++03. An implicitly-declared copy ctor is implicitly defined when it is used, i.e. when you copy an object, as in statement 2. – Jonathan Wakely Jun 01 '12 at 20:07

3 Answers3

8

For class to be copyable, it needs to have a copy constructor. Whether you write your own, or compiler generates one for you, it doesn't matter — it has to be available for test a; test b(a); to be a valid operation.

You explicitly force compiler to delete the copy constructor — this is new version of old "make copy constructor private" trick. It disallows copying. So don't be surprised that you can't copy. Because you told the compiler to not allow it.

Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
2

The standard word on implicitly generated copy constructors is [class.copy]/7:

If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

and [class.copy]/13:

A copy/move constructor that is defaulted and not defined as deleted is implicitly defined if it is odr-used (3.2) or when it is explicitly defaulted after its first declaration. [Note:The copy/move constructor is implicitly defined even if the implementation elided its odr-use (3.2, 12.2). —end note] If the implicitly-defined constructor would satisfy the requirements of a constexpr constructor (7.1.5), the implicitly-defined constructor isconstexpr.

So a copy-constructor is still generated for test, and its getting invoked by statement 2. I would believe that "Inside C++ Object Model" is talking about when a copy-constructor isn't trivial.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
0

This line:

test obj2(obj1)

is trying to call the copy constructor.

Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319