-1

In the following code, I traced by using debugger I fail to understand
1. why B b2() is never called but skipped.
2. Why auto_ptr calls base (A) destructor only when object created is derived (B)?

class A {
public:
    A(int x_) : _x(x_) {cout << "A::A( " << _x << ")" << std::endl; }
    A(const A& src) : _x(src._x) {cout << "A::A(copy " << _x << ")";}
    ~A() { std::cout << "A::~A " << std::endl; }
    int x() const { return _x; };
protected:
    int _x;
};
class B : public A {
public:
    B():A(0) {cout << "B::B( " << _x << ")";}
    B(A a):A(a.x()) {cout << "B::B(A) ";}
    ~B() { std::cout << "B::~B "; }
};
int main() {
    B b1(11); //which calls A(int) -> B(A a) -> {A::x() -> A(int)} -> ~A()}
    B b2();   //It's never called, why?
    std::auto_ptr<A> aptr(new B); //Calls A(0)->B()-> ~A() ==> why ~A() only but not ~B() ?
}
/*Actual Result:
B b1(11) => It prints following
        A::A(11)
        A::A(11)
        B::B(A)
        A::~A
/// Why B b2() is not called???
auto_ptr<A> aptr(new B) => It prints following. Why ~B() is not called?
    A::A(0)
    B::B(0)
    A::~A
B b1(11) destructors => It prints following
    B::~B
    A::~A */
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
sheikhazad
  • 31
  • 6
  • 1
    Because it's not a constructor call, it's a function declaration. –  Mar 25 '19 at 23:58
  • `B b2;` or `B b2{};` is what you want – Max Vollmer Mar 26 '19 at 00:03
  • 1
    https://stackoverflow.com/questions/180172/default-constructor-with-empty-brackets – Nikos C. Mar 26 '19 at 00:09
  • `B b2(); ` this is misleading to the compiler: It thinks a function prototype that takes 0 argument and returns `B` object. So the correct way remove the parenthesis. `B b;` Now there's no way that the compiler consider it a function prototype. – Raindrop7 Mar 26 '19 at 00:13
  • It seems you asked two questions though. You should only make one post per question. The quick answer to your secondary question is that you should make your destructors `virtual` when your class is polymorphic (meaning you create `B` objects but store them in `A` pointers.) Also, please never use `std::auto_ptr`. This is a buggy type and has been deprecated in C++. Use `std::unique_ptr` instead. – Nikos C. Mar 26 '19 at 00:15

2 Answers2

3
  1. why B b2() is never called but skipped.

B b2(); declares a function, not a variable. It's called Most vexing parse.

This is how you declare a variable with default constructor:

B b2;
  1. Why auto_ptr calls base (A) destructor only when object created is derived (B)?

Because your base class's destructor is not virtual. Classes intended to be used as a base almost always should have a virtual destructor.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
2

Why ~B() is not called? Only A::A(0)

In C++ the destructors have to be declared as virtual or don't allow class extension.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
Dr Phil
  • 833
  • 6
  • 18