1

i ran the code below to assign parent portion of objet to child object. but as described inline, c style downcast behaves something unexpected. what happen there? please refer to the comment below.

    struct A {
    public:
        int i{};
        A() { std::cout<<"A constructor called\r\n"; }
        ~A() { std::cout<<"A destructor called\r\n"; }
    };

    struct B : public A {
        B() { std::cout<<"B constructor called\r\n"; }
        ~B() { std::cout<<"B destructor called\r\n"; }
    };

    A a{};
    B b{};
    a.i = 1;
    (A)b = a;  // this code no effect and surprisingly the destructor of A is called.
               // there was no compiler warning (g++ (Ubuntu 11.2.0-7ubuntu2) 11.2.0)
    std::cout<<a.i<<std::endl;
    std::cout<<b.i<<std::endl;
    A& ra = b;
    ra = a;     // A portion of B is initialized as expected
    std::cout<<b.i<<std::endl;

this code prints as

A constructor called
A constructor called
B constructor called
A destructor called <-- please note here
1
0
1
B destructor called
A destructor called
A destructor called

kile
  • 43
  • 3
  • 1
    `(A)b` causes a new `A` to be copy constructed see live - https://godbolt.org/z/ox11h76sd . Note the values of `this` are output to enable the tracking object creation / destruction. I have also commented out the assignment for clarity. – Richard Critten Nov 07 '21 at 10:33
  • o.k, c style downcasting on object causes copy construction. that's why the constructor of A is not called. then is this c++ behavior ? – kile Nov 07 '21 at 12:51

1 Answers1

2

magic is here: (A)b = a;

what happend is:

  1. call A's copy constructor and create a new [class A object]. it's a temporary object, and it's destoryed after this statement. so print [A destructor called <-- please note here]
  2. call A's operator= on the temporary object. it's only effect the temporary object instead of original b;
Jason
  • 36,170
  • 5
  • 26
  • 60
niu2x
  • 141
  • 1
  • 5
  • what i don't understand is why typecasting makes a temporal object. is this expected c++ statement behavior ? – kile Nov 07 '21 at 13:23
  • it's expected; if you don't want a temp object. you should use pointer or reference. eg: (A&)b = a; if you use (A)b, you cast b to class A , there must be a new memory block ( temp object ) hold the cast value – niu2x Nov 07 '21 at 14:06
  • now i understand. but i think the syntax is not intuitive. since other primitive types don't make temporal object when it is casted. thank you for your kind reply. – kile Nov 07 '21 at 17:24