0

thanks in advance for any help you can give. I am struggling with figuring out what exactly goes into a destructor because I haven't found a great explanation of really how you implement the idea with code. My textbooks and a couple of different things I've read explain that a destructor is essentially a method that is called for an abstract data type (ADT) that helps to release any resources/memory used by an ADT object. My textbook code example though literally just has a cout statement inside of the destructor that says "The object is about to be destroyed" which you can imagine isn't particularly helpful.

I am working on a stacks project where we're creating a stack of pointers to a struct object called Data (which does not have a destructor, read a little bit about why that is earlier) which contains two attributes: int ID and string data. Then the stack itself only has two attributes: int top (holds the top value for peek and pop functions) and the array of Data pointers.

So do I need to delete top and delete the stack of pointers? Can I just delete the stack of pointers as a whole or do I need to iterate through the stack and delete everything inside of it before deleting the stack array itself? If I do need to delete each pointer, can I just delete the pointer? Or do I need to figure out how to also delete the information that is inside of that memory location where the pointer is pointing? And do I do all of those things using the delete keyword?

Just trying to wrap my head around what all I need to specifically target when deleting things in the destructor. Once I know that much, I think that I can figure out how to do the actual writing by googling for syntax and testing out in the IDE/terminal, double checking things with the professor if syntax isn't quite working, etc.

Normally I'd ask these things to my professor in class, but the class itself is for data structures and algorithms so I don't want to interrupt those topics to ask something that feels sort of regressive. I think maybe these things were supposed to be covered in the prerequisite course but I took that class a while ago and it doesn't seem that these things were really covered well based on that textbook I still have (and there was no lecture because it was online).

I really want to learn these concepts deeply and understand the architecture behind them as much as possible so that I'm prepared well for writing good code and working in a professional environment. Thank you again for any help you all can give!

Allison
  • 31
  • 1
  • 5

2 Answers2

0

To requote your questions:

So do I need to delete top and delete the stack of pointers? Can I just delete the stack of pointers as a whole or do I need to iterate through the stack and delete everything inside of it before deleting the stack array itself? If I do need to delete each pointer, can I just delete the pointer?

That really depends on how you implemented your array of pointers, if each pointer has is not pointing to another array, list, or some object of some kind, and given your array is a static array then, simply typing delete arrayName[] is fine. But if your pointers point to another array or list or object of some kind, then you would need to set variables for those objects or list or array to their default values and delete them one by one.

user4581301
  • 33,082
  • 7
  • 33
  • 54
Yunfei Chen
  • 630
  • 1
  • 8
  • 20
0

Here are the three ways to write a destructor for an abstract class:

  1. The class may be deleted polymorphically:

    class BaseClass
    {
        public:
           virtual ~BaseClass() = default;
    };
    
  2. The class may be used polymorphically, but deletion always uses the exact runtime type (e.g. std::make_shared() acts this way)

    class BaseClass
    {
        protected:
           /* not virtual */ ~BaseClass() = default;
    };
    
  3. The class is just a fancy namespace (namespaces are missing some features) and is used as a container but never instantiated:

    template<stuff> class FancyNameSpace
    {
        private:
           /* virtual doesn't matter */ ~FancyNamespace() = delete;
    };
    

A class hierarchy should always be using the compiler-generated default destructor, with only changing the access and virtualness. That's because acting as a base class is a separate responsibility from managing a resource, so the Single Responsibility Principle says that the resource management should be moved to a helper class whose sole function is scope-based resource management (RAII).

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • I don't think this is what they are asking. The way I read the question, it seems they're trying to figure out automatic vs dynamic allocation and ownership. What do I release when, and how? – user4581301 Jul 01 '20 at 16:28
  • @user4581301: Yes it would help if the OP's professor used C++ terminology the same way as the rest of the world. You won't find "abstract data type" anywhere in the C++ standard, and on StackOverflow the tag [tag:adt] is Android Development Tools so seems totally off-topic for this question. – Ben Voigt Jul 01 '20 at 17:32
  • @user4581301 well I think I pretty much answered that question..... – Yunfei Chen Jul 01 '20 at 18:56
  • @YunfeiChen You got part of it, and about as much as anyone can without writing a couple chapters of a text book. I stopped writing after about a page that only covered a small portion of what was asked. I didn't even get to why the asker didn't need to delete the stack class's `top` member. Some questions take a book to explain in full detail. – user4581301 Jul 01 '20 at 19:05
  • The first one isn't abstract though (unless it has some pure virtual method that we don't see). `virtual ~BaseClass() = 0;` would make it abstract. Then adding `BaseClass::~BaseClass() = default;` outside the class definition would still keep it abstract but with a default destructor to not force subclasses to have to implement one. – Ted Lyngmo Jul 01 '20 at 20:17
  • @TedLyngmo: A destructor always needs a definition, even if it is pure virtual. The compiler will define a destructor by default in every class (including the subclass), so the programmer is never forced to implement one. As a result of the combination of these rules, making a virtual destructor pure is nearly pointless (although it does make the class abstract, it has zero impact on subclasses). – Ben Voigt Jul 01 '20 at 20:46
  • @BenVoigt Yes, I was totally off track there... :) I should have stopped at "_The first one isn't abstract though_". :-) – Ted Lyngmo Jul 01 '20 at 21:08