The problem of weird casting. The base is received in C ++.

I have three classes: Base, Derived (inherited from Base) and Stats (which uses the base).

The program creates a Derived object that can be deleted and reconstructed several times during program execution. It also sets up a Stats object that will be created only once, but it needs to call functions based on the Derived object. Because the Derived object can be restored, the Stats object will need a reference to the Base pointer, as the value of the pointer may change. However, when I create a new Derived basically, the link in the Stats class does not see the new object.

In the example below, d and m_obj are zero, then when I create a new instance of Derived, m_obj is still null. It makes no sense to me. What even more confuses if I changed the line Derived* d = 0; on Base* d = 0; It works great. 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; sf(); return 0; } 
+4
source share
2 answers

You create a link to a temporary Base * that points to what d pointed to (in this case NULL). This temporary is destroyed after the line that causes the constructor to complete execution. Congratulations, you just triggered undefined behavior! After that, everything can happen.

Essentially, this line reads like this if you extend what really happens:

 Stats s(d); 

really

 { Base * const tmp = d; Stats s(tmp); } 

Except, of course, s does not disappear, as in this example.

When d is of type Base * , then the compiler should not convert the type and therefore should not create temporary files.

+3
source

Your Stats actually gets a temporary copy of the d value. This is due to the fact that d is not of type Base * const & (but can be converted to).

+3
source

Source: https://habr.com/ru/post/1343846/


All Articles