I encounters a problem where I want to have a class in which its behavior can be customized by another class, for example, Foo’s constructor accepts a parameter of some type of class:
class Bar { //The default class that define behavior
};
template <typename T = Bar>
class Foo {
public:
Foo(T* t = 0) t_(t) {
if (t_ == 0) t_ = new T();
}
~Foo() {
delete t_;
}
}
Now if someone use Foo in a client code:
Foo foo;
Everything is fine. But, if we want to supply the custom class:
class Bar1 { };
Foo<Bar1> foo(new Bar1()); // This is OK
Bar1 b;
Foo<Bar1> foo(&b); // Error, b is not dynamically allocated
Is there any design pattern I can use to prevent this kind of mistakes? Or, is there any techniques or semantics where the user of Foo class can choose/specify who owns the bar object? So for example, the above Foo destructor can be like this:
~Foo() {
if (t_ is owned by this object) delete t_;
}
Bar or Bar1 or any class passed as t in Foo(T* t) might be a big object, so if it is possible I rather not to pass it by value.
Update:
What I have in mind is for the user to be able to do something like:
Foo foo(new Bar(1, 2, etc..));
//or this:
Bar bar(1, 2, etc..);
Foo foo(bar);
But if bar is a big object (for example, contains an array), then it would be inefficient to pass bar by value. The only way is to have bar passed by reference or pointer, but I also want the user to be able to use bar with parameterized constructor, and hence my confusion began.
Regarding to the auto variable scope, it would be safe if a user do something like:
int main() {
Bar1 bar1(1,2,3);
Foo foo(&bar1);
return 0;
}
As long as Foo does not delete bar1.
You can’t detect the difference between stack and heap allocation (the standard doesn’t even mention a stack), but that’s not the issue here.
Fooshould not be deleting things that it does not own. If it wants a copy for itself then it should just make a copy:Or if you need it to be a pointer:
You can’t just go around deleting things that people give you, and that’s regardless of whether you know if it’s stack or heap allocated. What if your
Foogoes anddeletes it but the calling code still wants to use it? Or what if that same object is passed into two of yourFooobjects and they bothdeleteit?Your option is either to make a copy, or not delete it.
An alternative to doing the copy would be to mark whether you are using your own or someone else’s:
In case you are wondering,
tis passed by const-ref in my previous solutions, not by value, so there is no excessive expense, although there could be an expense in the copying.