You're saying if A::print accessed an instance variable, it would segfault. The this pointer is null at a->print, but since it doesn't need it, the code executes fine.
Accessing memory that is not allocated is undefined behavior according to the standard. Undefined
means exactly that -- it could do anything; it needn't necessarily segfault.
I'm still trying to get my head around auto_ptr behavior. Consider the following code:
#include <iostream>
#include <memory>
using namespace std;
class A {
public:
A() {}
~A() { cout << "A destructed" << endl; }
void print() { cout << "A::print called" << endl; }
};
class B {
public:
B(auto_ptr<A>& a) : m_a(a) {}
void print() { m_a->print(); }
auto_ptr<A> m_a;
};
class C : public A {
public:
void print() { cout << "C::print called" << endl; }
};
int main() {
auto_ptr<A> c(new C);
B b(c);
b.print();
cout << "exiting" << endl;
}
When this runs, the output is:
A::print called
exiting
A destructed
Why wasn't C::print() called? I think the term Scott Meyers uses is "slicing" in the Effective C++ book. But the underlying type is a pointer, why isn't it a pointer to C in this case?