Can a C++ class determine whether it's on the stack or heap?

后端 未结 15 2207
有刺的猬
有刺的猬 2020-12-13 04:14

I have

class Foo {
....
}

Is there a way for Foo to be able to separate out:

function blah() {
  Foo foo; // on the stack
         


        
15条回答
  •  臣服心动
    2020-12-13 04:30

    There is a solution, but it forces inheritance. See Meyers, "More Effective C++", Item 27.

    EDIT:
    Meyers' suggestion is summarized in an article written by Ron van der Wal, which Meyers himself linked to in his blog (in this post):

    Tracking heap based objects

    As an alternative to the global variable approach, Meyers presents a HeapTracked class that uses a list to keep track of the addresses of class instances allocated off the heap, then uses this information to determine if a particular object resides on the heap. The implementation goes like this:

    class HeapTracked {
      // Class-global list of allocated addresses
      typedef const void *RawAddress;
      static list addresses;
    public:
      // Nested exception class
      class MissingAddress {};
    
      // Virtual destructor to allow dynamic_cast<>; pure to make
      // class HeapTracked abstract.
      virtual ~HeapTracked()=0;
    
      // Overloaded operator new and delete
      static void *operator new(size_t sz)
      {
        void *ptr=::operator new(sz);
        addresses.push_front(ptr);
        return ptr;
      }
    
      static void operator delete(void *ptr)
      {
        // Remove ‘ptr’ from ‘addresses’
        list::iterator it=find(addresses.begin(),
    
        addresses.end(), ptr);
        if (it !=addresses.end()) {
          addresses.erase(it);
          ::operator delete(ptr);
        } else
          throw MissingAddress();
      }
    
      // Heap check for specific object
      bool isOnHeap() const
      {
        // Use dynamic cast to get start of object block
        RawAddress ptr=dynamic_cast(this);
        // See if it’s in ‘addresses’
        return find(addresses.begin(), addresses.end(), ptr) !=
          addresses.end();
      }
    };
    
    // Meyers omitted first HeapTracked:: qualifier...
    list HeapTracked::addresses; 
    

    There is more to read on the original article: Ron van der Wal comments on this suggestion, and then demonstrates other alternative heap tracking methods.

提交回复
热议问题