I have three classes: Base, Derived (inherits from Base), and Stats (which uses a Base).
The program makes a Derived object, which may be deleted and reconstructed several times during the program’s execution. It also sets up a Stats object which will only be created once, but needs to call functions on the Base of the Derived object. Because the Derived object may be reconstructed, the Stats object will need a reference to a pointer of Base, since the value of the pointer may change. However, when I construct a new Derived in main, the reference in the Stats class doesn’t see the new object.
In the example below, d and m_obj both are null, then when I make a new Derived instance, m_obj still is null. This doesn’t make sense to me. What confuses even more, is if I change the line Derived* d = 0; to Base* d = 0;, it works fine. Any thoughts?
#include <iostream>
using namespace std;
class Base {
};
class Derived : public Base {
};
typedef Base* const base_ptr;
class Stats {
public:
Stats(Base * const &obj) : m_obj(obj) {
cout << "In Stats():" << endl;
cout << " m_obj = " << m_obj << endl;
}
void f() const {
cout << "In f:" << endl;
cout << " m_obj = " << m_obj << endl;
}
private:
base_ptr &m_obj;
};
int main() {
Derived* d = 0;
cout << "d = " << d << endl;
Stats s(d);
d = new Derived();
cout << "d (after new) = " << d << endl;
s.f();
return 0;
}
You are creating a reference to a temporary
Base *that points to whatdwas pointing at (NULL in this case). That temporary is destroyed after line that invokes the constructor finishes executing. Congratulations, you’ve just invoked undefined behavior! After that, anything can happen.Essentially, this line reads like this if you expand out what’s really happening:
really:
Except, of course,
sdoesn’t go away like it would in this example.When
dis of typeBase *then the compiler doesn’t have to do any type conversion and so doesn’t have to create any temporaries.