The problem is quite simple. I have a class that can be structured as the following:
class MyClass {
struct A {
// ...
};
struct B {
// ...
};
};
The problem is: the information in MyClass::B is useless after some time of precomputations, whereas MyClass::A must never be deleted (the program may be running for days). MyClass::B holds quite a large amount of information. I want to get rid of MyClass::B while keeping MyClass::A in the same memory position.
Is it possible to do this without modifying too much the data structure and not having to add anything else to MyClass::A (in particular, a pointer to MyClass::B)? If so, what would be the right way to implement it? Take in account that the program must be as memory-efficient as possible (and let us take that to the extreme). I use C++14 BTW.
(And extra question: It is possible to delete the chunk corresponding to MyClass::B from MyClass?)
First or all that's a class declaration. You can't delete a part of the class declaration. You probably have something more like this:
// The exact place of the declaration doesn't matter actually
class A {...};
class B {...};
class C {
A a;
B b;
};
Just change it to use a pointer (in this day and age a smart pointer, like std::unique_ptr):
class C {
A a;
std::unique_ptr<B> b;
void FinishTaskThatRequiredB() {
b.reset(); // calls B::~B() and frees the memory.
}
};
Okay, let's elaborate a bit on what I wrote: “either the life of B is tied to that of MyClass, or it is independent. In that latter case, you must keep track of it in some way”.
Putting the context back from the question:
Is ensues that you want to keep track of it in some way. How? Well, that depends on the rules on the life time.
nullptr when it is useless, and dynamically allocated when it is useful is pretty much the only solution.But here we have more knowledge: B exists first, then becomes useless and remains so forever. In other terms, you don't need B after some initial building steps used to create A.
There is a pattern that does exactly this: the builder pattern. Its purpose is to encapsulate a complex building operation, maybe tracking some state, until it has built some object, at which point it becomes useless and can be destroyed.
class ABuilder
{
public:
setSomeInfo(int);
doSomeComputation(......);
// etc
A get(); /// finalize building of A
private:
int someInfo_ = 0;
};
// somewhere else
auto b = ABuilder();
b.setSomeInfo(42);
b.doSomeComputation(......);
auto a = b.get();
// b is no longer used past that point
// delete it if it was allocated dynamically
// or let it go out of scope if it was automatic
From your example, it would map somewhat like this:
A is still A.B is ABuilder.MyClass is not needed.If you had provided actual class names and purpose, it would have been easier to make the examples meaningful ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With