e.g.

class B
{
public:
	virtual ~B() {printf("Base class Destructor");}
};

class D
{
public:
	~D() {printf("Derived class Destructor");}
};

Is it somehow possible to altogether avoid printing 'Base class Destructor' when an object of class D is destructed (of course without causing a memory leak)..
If you need to know, I'll later tell you the actual problem which I'm trying to solve this way.

Recommended Answers

All 12 Replies

if the base class were responsible for cleaning up memory within its destructor, then stopping that code being called would of course cause a memory leak.

I can't see how that could benefit you, unless you have some reason why you'd intentionally not want that memory to be released - if this is the case, then you should think about changing the design of your program (move the responsibility for that memory block elsewhere) - or create a copy before that memory is cleaned up.

Whatever code you wish to prevent being run in your base class destructor, you might think about moving it out of that destructor, or perhaps setting a flag which dictates whether or not some or all of that destructor is used

class base
{
    const bool cleanup;
public:
    base() : cleanup(true) {}
    base(bool b) : cleanup(b) {}
    ~base()
    {
        if(cleanup)
        {
            std::cout << "base destructor" << std::endl;
        }
    }
};

class foo : public base
{
public:
    foo() : base(false) {}
    ~foo()
    {
        std::cout << "foo destructor" << std::endl;
    }
};

class bar : public base
{
public:
    ~bar()
    {
        std::cout << "bar destructor" << std::endl;
    }
};

int main()
{
    foo f;
    bar b;
}

if the base class were responsible for cleaning up memory within its destructor, then stopping that code being called would of course cause a memory leak.

I can't see how that could benefit you, unless you have some reason why you'd intentionally not want that memory to be released - if this is the case, then you should think about changing the design of your program (move the responsibility for that memory block elsewhere) - or create a copy before that memory is cleaned up.

Whatever code you wish to prevent being run in your base class destructor, you might think about moving it out of that destructor, or perhaps setting a flag which dictates whether or not some or all of that destructor is used

class base
{
    const bool cleanup;
public:
    base() : cleanup(true) {}
    base(bool b) : cleanup(b) {}
    ~base()
    {
        if(cleanup)
        {
            std::cout << "base destructor" << std::endl;
        }
    }
};

class foo : public base
{
public:
    foo() : base(false) {}
    ~foo()
    {
        std::cout << "foo destructor" << std::endl;
    }
};

class bar : public base
{
public:
    ~bar()
    {
        std::cout << "bar destructor" << std::endl;
    }
};

int main()
{
    foo f;
    bar b;
}

Thanks man(or woman, pardon me) for the speedy reply and a pretty good explanation.. Actually, now even I'm thinking whether or not it's a wise strategy to consider doing that(escaping base's destructor).. Well my original problem was that the base class is in a 3rd party lib and hence source code is not in my control(And i'm not trying to make it a difficult problem, it was originally so), and the base class contains some arrays it allocates dynamically and plays with them, plus it doesn't let me override(not virtual, heck it's private, i can't even use it) its copy constructor(and I'm using std::vector of objects of Derived class), so to avoid creating multiple copies of the base class objects(which contain some security related data and hence should not be plainly copied into another derived class object else double destruction will be called with the same security id etc.), that's why I'm trying to bypass the base class destructor until I'm done using it in as many derived class objects as i wish.. The problem is actually even more complicated than I have described and avoiding memory leak is of prime essence.

You might consider making your derived class completely independent of the base class.

If you have sufficient control of the source, you could then redesign your derived class to add a pointer to a pre-existing instance of the base object. This would imply a private pointer variable with some sort of setPointerTarget and other similar accessor methods or similar. Unfortunately, even though I know it is theoretically possible, I can not demonstrate it, hopefully someone else can. I haven't gotten into classes enough to know how.

Thanks Fbody, but I'm afraid that won't work for two reasons: (a)I have only binary and header files of the base class, no source code, (b) I'm sure even if I somehow get the source code, (unless i change some modifiers and part the implementation of the base class which would mean going into copyright infringement issues and other complexities) it'll be pretty messed up as I'm sure the base class depends on many other classes and so on, it's a dead end(figuratively of course).
Let me state my problem more clearly as i think i didn't state it clearly last time..
Let me denote a base class object as B and a derivd class D.. Each B on its construction is provided a given a unique ID which has not been allocated to any other B before it.. When I push_back D(remember it gets its B on construction which has its unique id) into a std::vector, inside push_back function D is automatically copied using its copy constructor. Let's call the later version as D_ and which gets its own B_. Inside the copy constructor of D, B's id is copied to B_ as it calls B's copy constructor instead of the default constructor. Now once push_back returns, at some point D is to be destructed as it's just a temp object whose copy(D_) is maintained in the vector now.. This destructor of D calls destructor of B(which I'm trying to avoid) with B's id(same as the id of B_). So in system's memory, this id has been freed. Now at a later point when D_(or rather I should say B_) is used, it causes trouble. So I was thinking if I could somehow escape B's destructor, and later call only B_'s destructor and be done..
I know the simplest solution is to use std::vector<D*> instead of std::vector<D> which would avoid the copying of B part, but what if I can't do that?

I understand that you do not have access to the source for the base class and that you can not modify it. I was referring to your derived class that is trying to inherit from the base. Please read my post again more carefully.

To sumarize it:
You might be better off setting up a "uses" style relationship rather than an "is a type of" relationship between your "base" class and your "derived" class.

Another option would be to set up your vector as a vector of pointers. You would then push a pointer to the original object(s) into the vector instead of a copy of the object.

Okay sorry, I hadn't read your post after the first sentence which made me think that you were hinting at removing base class from picture wholly. Also, I didn't quite understand your concept about the pre-exisiting instance's pointer. Were you talking about 'has-a' to replace 'is-a'?
Anyway here' s another bit of the problem which I'd not disclosed so far: The actual problem due to which I couldn't use a 'has-a' relationship between D and B initially (otherwise it was my first instinct too) was that I'm also using a CustomList object which accepts objects of type A* only (A is a parent of B) for objects of D, so D has got to derive from B.

I think you got the basic idea of the post.

That extra information is actually rather critical and makes a big difference. So this list accepts pointers to class A objects? Did I read that correctly?

If that's the case, you shouldn't be able to copy D objects directly into it anyway.

Assuming the inheritance is set up correctly, you would have to insert pointers specified as class A pointers that point to class D objects.

This is getting into uncharted territory for me, but I suspect something like:

classAPointers.push_back(new D);

would work.

There is an immediate issue I can see. How do you delete the object(s) to prevent any leaks?

Perhaps you misinterpreted(though i may be wrong) when I told you about the CustomList, actually there is std::vector<B> as well as CutomList<A*> both working.. I revealed the existence of CustomList, so as to explain why had to derive D from B. So, what we insert into the CustomList doesn't solve the problem of the id copy or B's copy constructor during the use of std::vector<B>. By the way

classAPointers.push_back(new D);

is not so difficult in terms of handling memory leak. Just before erasing any item from classAPointers, use delete operator on the pointer saved there(though don't forget proper use of virtual destructors or else hell will break lose.. :D). i.e. like

for (CutomList<A*>::iterator it = classAPointers.begin(); it != classAPointers.end(); it++)
{
	delete (*it);
	classAPointers.erase(it);
}

If you meant something else, please enlighten me some more code..
I know I'm turning it into a mess by not using std::vector<B*> instead of vector<B>, but well I want to disturb the design document that I've received from my boss at little as possible.

I think I'm getting more confused instead of less. A couple questions that will hopefully help clarify:

1.) Is the ID# Defined in B or is it defined in A then inherited by B? (I believe this may be irrelevant, I'm not sure.)

2.) It seems you are trying to store D objects into a vector of B elements. Is this correct? I don't know of a way to do this without pointers.

3.) You only have the source for the D class/objects and the user code. The A and B objects are part of the provided library. Is this correct?

No problem, I'll answer all your questions.. Anyway as I already said the true problem(which I haven't described yet and don't wish to either) is actually way more complicated than the part I'm discussing.

1.) Is the ID# Defined in B or is it defined in A then inherited by B? (I believe this may be irrelevant, I'm not sure.)
I'm not sure(will have to check), but I don't think that should matter.. Anyway assume it to be in A for the time being.

2.) It seems you are trying to store D objects into a vector of B elements. Is this correct? I don't know of a way to do this without pointers.
Okay. My bad! Toward the end of my last post, I by mistake said std::vector<B> & std::vector<B*>. Actually I'm storing D objects into std::vector<D> and CustomList<A*>. If your wanna know what for - std::vector<D> is used for making a tree structure, where every D object has children stored in std::vector<D>(a data member), CustomList<A*> is very like a big list where every A object(by pointer i mean) is stored for drawing purpose. If it helps, A is abstract class(but it has derivatives other than B), B isn't abstract.

3.) You only have the source for the D class/objects and the user code. The A and B objects are part of the provided library. Is this correct?
Yes, that is correct.

I think you're going to have to talk to your engineer / boss, or whoever wrote your Design Document. You're going to have to figure out what they were thinking. You will also have to see if you can change it from std::vector<D> to std::vector<D*>. If he won't let you change it, I'm afraid I'll have to bow out of this conversation, I just won't be of any more use.

As I understand it, a std::vector has a certain amount of Dynamic Memory Allocation built in to it. Every time you call [I]vectorName[/I].push_back([I]objectName[/I]) it checks the current size of the vector relative to its capacity. If there isn't sufficient capacity, it copies the current vector to a new address range and allocates more space adjacent to the new location. As a result of the re-allocation, the constructor(s) and destructor(s) for each object contained within the original vector are called to create the new vector and delete the old one. This all happens behind the scenes, out of your control.

Plus if you change the vector's type from actual objects to pointers to objects, that will allow you to use Dynamic Allocation to create each subsequent object as required.

Thanks Fbody! I guess you are right.. I'll have to get the design fixed. Or the series of nightmares will never stop. Anyway I guess also should mark this thread as solved..

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.