2

Below is my sample program:

When I compile and run the below program I get output:

#include <iostream>
class A 
{
   public:
   explicit  A() 
      {
        std::cout << "A CTOR\n" << std::flush;
      }
    ~A()
      {
         std::cout << "A DTOR\n" << std::flush;
      }
      A(const A & a) 
      {
          std::cout << "A DEEP COPY CTOR\n" << std::flush;
      }
      void operator = (const A & a) 
      {
          std::cout << "A DEEP COPY = CTOR\n" << std::flush;
      }
      A(A && a) 
      {
          std::cout << "A DEEP COPY MOVE CTOR\n" << std::flush;
      }
      void operator = (A && a) 
      {
          std::cout << "A DEEP COPY MOVE = CTOR\n" << std::flush;
      }
};
int main() 
{
 A a = A();
 A b(A());
}

Compile and run the binary:

$ c++ -std=c++14 try47.cpp

A CTOR
A DTOR

I was expecting the A's default constructor would be called followed by copy assignment ctor in first line and move ctor for second line? But this does not seems to happen? Why? I think I am missing some basic understanding here?

Please clarify when will which CTORs will actually be called?

Programmer
  • 8,303
  • 23
  • 78
  • 162
  • 1
    The second line is a function declaration, not a variable definition+initialization; `b` is a function, not an object of type `A`. The first line, conceptually, is a copy initialization - but the copy constructor is [elided](https://en.cppreference.com/w/cpp/language/copy_elision). – Igor Tandetnik Oct 16 '18 at 04:51
  • I added explicit keyword but still the same output – Programmer Oct 16 '18 at 04:55
  • assignment operators are not constructors – M.M Oct 16 '18 at 08:09
  • Possible duplicate of [Most vexing parse confusion](https://stackoverflow.com/questions/17060725/most-vexing-parse-confusion) – Joris Timmermans Oct 16 '18 at 08:14

1 Answers1

2

Don't let the = operator throw you off. What is happening in the first line is just a default constructor call. There is no need for the copy-assignment (compiler elides this) because you are not assigning anything to a.

But the following will result in what you are looking for:

 A a, c; //A CTOR
 c = a; //A DEEP COPY = CTOR because c is being assigned the value of a

The second line is just a function declaration.

A b(A());

b is a function which takes A as a parameter and returns A. This ambiguity is commonly known as the most vexing parse.

The CPP standard draft (N4713) states this:

9.8 Ambiguity resolution [stmt.ambig]

  1. There is an ambiguity in the grammar involving expression-statements and declarations: An expression statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.

  2. [ Note: If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not apply. The whole statement might need to be examined to determine whether this is the case.

P.W
  • 26,289
  • 6
  • 39
  • 76
  • Because line2 is a function declaration and not an instantiation of A. Please see second part of the answer. – P.W Oct 16 '18 at 05:07
  • Thanks - can you please provide if there are any further rules for calling CTORs - it will be highly helpful - the same is cause what are the CTORs that we should write - take care - cause otherwise we will land up making a large class object being copied silently be it shallow or deep – Programmer Oct 16 '18 at 05:13
  • Effective C++ by Scott Meyers has a whole chapter on this. It is chapter 2 of that book. Very well explained. Your library should have a copy. – P.W Oct 16 '18 at 05:16