0

I just start learning c++11 for a short time and met a problem I don't understand. Here is the simplified example I met in a code base:

#include <functional>
#include <iostream>
#include <memory>
#include <string>
#include <utility>

class Dumpper {
 public:
  Dumpper(std::function<void()> func) : mDumpFunc(std::move(func)) {}

  ~Dumpper() {
    mDumpFunc();
  }

 private:
  std::function<void()> mDumpFunc;
};

class Object {
 public:
  std::string getInfo() {
    return "Object's information";
  }
};

class Base {
 protected:
  void InitDumpper(std::function<void()> func) {
    mDumpper.reset(new Dumpper(func));
  }
 private:
  std::unique_ptr<Dumpper> mDumpper;
};

class Derived : public Base {
 public:
  Derived(Object* object) : Base(), mObject(object) {
    InitDumpper(std::bind(&Derived::DumpFunc, this));
  }
 private:
  void DumpFunc() {
    std::cout << "Call DumpFunc, object = " << mObject->getInfo() << std::endl;
  }

  Object* mObject;  // Not owned.
};

class Test {
 public:
  Test() {
    mObject.reset(new Object);
    mDerived.reset(new Derived(mObject.get()));
  }
 private:
  std::unique_ptr<Derived> mDerived;
  std::unique_ptr<Object> mObject;
};

int main(int argc, char *argv[])
{
  Test test;
  return 0;
}

Based on my understanding, when Test is destructed, mObject is destructed first, then mDerived is destructed, then Base then Dumper. When Dumpper is destructed, mDumpFunc is called, in which member function of mObject is called. But why the member function can be called after mObject is destructed?

pyjamas
  • 9
  • 1
  • Are you asking why using an invalid pointer *seems to work*? – Bo Persson Jul 28 '16 at 17:53
  • 1
    Undefined behavior is undefined. One perfectly valid runtime consequence of undefined behavior is code that looks like it works. Another is nasal demons. – Barry Jul 28 '16 at 17:54
  • 1
    You will see the problem if you try to access some data member of the destroed object. object->getInfo() from compiler point of view looks like getInfo(object) and if you do not access data member of the object, you suppose that everything is ok, but this is only UB. – AnatolyS Jul 28 '16 at 17:56
  • 1
    You seem to know more C++ than the person who wrote that code base :-) – aichao Jul 28 '16 at 18:00
  • Thanks, now I understand. One more question: Is calling `Derived::DumpFunc` in `Dumpper` after the destruction of `Derived` an undefined behavior as well? – pyjamas Jul 28 '16 at 18:11

0 Answers0