Suppose there is a hierarchy of two classes (class Derived: public Base). Both these classes have big memory footprint and costly constructors. Note that nothing in these classes is allocated in heap: they just have a big sizeof.
Then there is a function with a fast path (executed always) and a slow path (executed conditionally). Fast path needs a Base instance, and slow path needs a Derived instance constructed from existing base. Also, slow path decision can be made only after the fast path.
Current code looks like this:
void f()
{
Base base;
/* fast path */
if (need_slow_path) {
Derived derived (base);
/* slow path */
}
}
This is inefficient, because the base needs to be copied into derived; also the base is allocated twice and there is a risk of overflowing the stack. What I want to have:
allocate memory for Derived instance
call Base ctor on it
execute the fast path
if needed, call Derived ctor on the existing Base instance and execute the slow path
Is it possible in C++? If not, what are possible workarounds? Obviously, I'm trying to optimize for speed.
I am afraid this is not possible just as you wrote - any constructor of Derived must call a constructor of the Base subobject, so the only way to do that legally would be to call Base's destructor first, and I believe you don't want that.
However, it should be easy to solve this with a slight redesign - prefer composition over inheritance, and make Derived a separate class that will store a reference (in the general sense; it can of course be a pointer) to Base and use it. If access control is an issue, I feel a friend is justified here.
You should change your design slightly to change your reliance on inheritance to that on composition.
You could encapsulate members of derived class (not present in the base class) into another class, and keep it's null reference in the derived class.
Now directly initialize derived class without initializing new class's object.
Whenever slow path is required, you can initialize and use it.
Benefits
Inheritance relationship between derived and base class is preserved.
Base class object is never copied.
You have lazy initialization of derived class.
I can fake it.
Move/all the data of derived into an optional (be it boost or std::ts::optional proposal for post C++14, or hand rolled).
Iff you want the slow path, initialize the optional. Otherwise, leave it as nullopt.
There will be a bool overhead, and checks when you assign/compare/destroy implicit. And things like virtual functions will be derived (ie, you have to manage dynamic dispath manually).
struct Base {
char random_data[1000];
// virtual ~Base() {} // maybe, if you intend to pass it around
};
struct Derived:Base {
struct Derived_Data {
std::string non_trivial[1000];
};
boost::optional< Derived_Data > m_;
};
now we can create a Derived, and only after we m_.emplace() does the Derived_Data get constructed. Everything still lives is in one contiguous memory block (with a bool injected by the optional to track if m_ was constructed).
Not sure if you can do exacactly what you want i.e execute "fast" path before second contructor but i think you use 'placement new' feature - manually call contructors based on need_slow_path predicate. i.e but that changes flow a little:
allocate memory for Derived instance
call Base or Derived ctor on it
execute the fast path
execute the slow path (if needed(
The example code
#include <memory>
void f(bool need_slow_path)
{
char bufx[sizeof(Derived)];
char* buf = bufx;
Derived* derived = 0;
Base* base = 0;
if (need_slow_path ) {
derived = new(buf) Derived();
base = derived;
} else {
base = new(buf) Base();
}
/* fast path using *base */
if (need_slow_path) {
/* slow path using *base & * derived */
}
// manually destroy
if (need_slow_path ) {
derived->~Derived();
} else {
base->~Base();
}
}
Placement new is well described here: What uses are there for "placement new"?
Can you define move copy con't in your compiler ?
There is an excellent explanation (although a bit long ) here
https://skillsmatter.com/skillscasts/2188-move-semanticsperfect-forwarding-and-rvalue-references
I don't have experience with move semantics so I might be wrong but since you want to avoid coping the base object when passing it to the derived class move semantics should do the trick
First extract constructor code into initializing methods both for Base and Derived.
Then I would make the code similar to this:
void f()
{
Derived derived;
derived.baseInit();
/* fast path */
if (need_slow_path) {
derived.derivedInit();
/* slow path */
}
}
It's a good idea to extract classes and use composition as Tanmay Patil suggested in his answer.
And yet another hint: If you haven't done already, dive into Unit-Tests. They will help you dealing with huge classes.
Perhaps instead of a class and constructors, you need a plain-old-struct and initialization functions here. You’ll be giving up a lot of the C++ conveniences, of course, but you’ll be able to implement your optimization.
Related
I will describe my problem using a dummy example. Say we have a program of this architecture:
Parent class: Quadrilateral
Child classes: Rectangle, Rhombus, ...
First, a vector<Rectangle> and vector<Rhombus> are generated and make use of their child class properties. Later on, I would like to combine all quadrilaterals, i.e. combine both vectors into a single vector<quadrilateral>, since I no longer need the child class properties. Combining both vectors into one has the advantage that I can pass a reference to vector<quadrilateral> to other parts of my program where it is combined with data from other classes.
So my question is as follows: Is it possible to make a Quadrilateral out of a Rectangle by keeping only the parent variables from the Rectangle? Or is this a really bad idea and is there a much more elegant way to implement this?
EDIT:
after learning from the answers that this is referred to as slicing, I have read about it in What is object slicing?. I have decided to go with Mohamad's suggestion of using vectors of pointers instead, because I think it is an elegant solution that will likely give me the best performance.
Yes you can definitely do this by 'slicing' the derived portion of the object.
class Base {};
class Derived : public Base {};
Derived d;
Base b = d; // derived portion is sliced here
However in practise, I have never seen anyone who deliberately chose to slice their objects. We are usually warned against this as a 'gotacha' of C++.
Why not use a vector of pointers instead:
vector<Rectangle*>;
vector<Rhombus*>;
vector<quadrilateral*>;
That way no slicing occurs and you might gain from a performance boost if those classes are large since any copying the vectors might do would be on pointers and not entire objects.
Yes, you can do this. You can create parent objects from child objects, as in following example:
struct Base { int base; };
struct Derived : Base { int derived; };
Derived der;
Base base = der;
The process is called slicing, and it works here because Base class will have default copy constructor, taking a const reference to Base. Since derived can be automatically converted to const reference to it's base, everything works like the charm. I am not sure about overall design, though. Usually slicing is to be avoided.
Following some questions in the comments, I believe, some clarification is in order.
Contrary to it appearance, Base base = der; does not call assignment operator. Instead, it calls copy constructor - this is the semantic of variable declaration. It is equivalent of Base base(der). Here is more intruiging example:
struct A {
A(int ) { };
A() = default;
// A(const A& ) = delete;
};
A a = 5; // Are your eyes fooling you?
Do not believe your eyes! There is never an operator= called - there is no even operator= in A defined. Instead, semantically A(int) constructor is called to create a temporary A, followed by copy constructor to create the a object. However, compilers usually optimize the call to copy-constructor away, and there is no redundant temporary copy created. In order to make sure this the case, uncomment copy-constructor marked delete, and the program will refuse to be compiled.
We use a framework that relies on memcpy in certain functions. To my understanding I can give everything that is trivially copyable into these functions.
Now we want to use a simple class hierarchy. We are not sure whether we can have a class hierarchy that results in trivially copyable types because of the safe destruction. The example code looks like this.
class Timestamp; //...
class Header
{
public:
uint8_t Version() const;
const Timestamp& StartTime();
// ... more simple setters and getters with error checking
private:
uint8_t m_Version;
Timestamp m_StartTime;
};
class CanData : public Header
{
public:
uint8_t Channel();
// ... more setters and getters with error checking
private:
uint8_t m_Channel;
};
The base class is used in several similar subclasses. Here I omitted all constructors and destructors. Thus the classes are trivially copyable. I suppose though that the user can write a code that results in a memory leak like this:
void f()
{
Header* h = new CanData();
delete h;
}
Is it right that the class hierarchy without the virtual destructor is a problem even if all classes use the compiler's default destructor? Is it therefore right that I cannot have a safe class hierarchy that is trivially copyable?
This code
Header* h = new CanData();
delete h;
will trigger undefined behavior since §5.3.5/p3 states:
In the first alternative (delete object), if the static type of the object to be deleted is different from its
dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the
static type shall have a virtual destructor or the behavior is undefined
and regardless of not having dynamically allocated objects contained in your derived class (really bad if you have), you shouldn't do it. Having a class hierarchy without the base class virtual destructor is not a problem per se, it becomes a problem when you try to mix static and dynamic types with delete.
Doing memcpy on a derived class object smells of bad design to me, I would rather address the need for a "virtual constructor" (i.e. a virtual clone() function in your base class) to duplicate your derived objects.
You can have your class hierarchy that is trivially copyable if you make sure that your object, its subobjects and base classes are trivially copyable. If you want to prevent users referring to your derived objects via base classes you could, as Mark first suggested, render the inheritance protected
class Header
{
public:
};
class CanData : protected Header
{ ^^^^^^^^^
public:
};
int main() {
Header *pt = new CanData(); // <- not allowed
delete pt;
}
Notice that you won't be able to use base pointers at all to refer to derived objects due to §4.10/p3 - pointer conversions.
If you delete a pointer to a derived type held as its base type and you don't have a virtual destructor, the derived types destructor won't be called, whether it's implicitly generated or not. And whether its implicitly generated or not, you want it to be called. If the derived type's destructor wouldn't actually do anything anyway though, it might not leak anything or cause a problem. If the derived type holds something like a std::string, std::vector, or anything with a dynamic allocation, you want the dtors to be called. As a matter of good practice, you always want a virtual destructor for base classes whether or not the derived classes destructors need to be called (since a base class shouldn't know about what derives from it, it shouldn't make an assumption like this).
If you copy a type like so:
Base* b1 = new Derived;
Base b2 = *b1;
You will only invoke Bases copy ctor. The parts of the object which are actually from Derived will not be involved. b2 will not secretly be a Derived, it will just be a Base.
My first instinct is "don't do that - find another way, a different framework, or fix the framework". But just for fun let's assume that for certain your class copy doesn't depend in any way on the copy constructor of the class or any of its comprised parts being called.
Then since you're clearly inheriting to implement rather than to substitute the solution is easy: Use protected inheritance and your problem is solved, because they can no longer polymorphically access or delete your object, preventing the undefined behavior.
It's almost safe. In particular, there is no memory leak in
Header* h = new CanData();
delete h;
delete h calls the destructor of Header and then frees the memory pointed to by h. The amount of memory freed is the same as was initially allocated at that memory address, not the sizeof(Header). Since Header and CanData are trivial, their destructors do nothing.
However, you must provide a virtual destructor to base even if it does nothing (by requirement of the standard to avoid undefined behaviour). A common guideline is that a destructor for a base class must be either public and virtual or protected and nonvirtual
Of course, you must beware slicing as usual.
Thanks all for posting various suggestions. I try a summarizing answer with an additional proposal for the solution.
The prerequisite of my question was to reach a class hierarchy that is trivially copyable. See http://en.cppreference.com/w/cpp/concept/TriviallyCopyable and especially the requirement of a trivial destructor (http://en.cppreference.com/w/cpp/language/destructor#Trivial_destructor). The class cannot need a destructor implemented. This restricts the allowed data members, but is fine for me. The example shows only C-compatible types without dynamic memory allocation.
Some pointed out that the problem of my code is undefined behaviour, not necessarily a memory leak. Marco quoted the standard regarding this. Thanks, really helpful.
From my understanding of the answers, possible solutions are the following. Please correct me if I am wrong. The solution's point is that the implementation of the base class must avoid that its destructor can be called.
Solution 1: The proposed solutions use protected inheritance.
class CanData : protected Header
{
...
};
It works but avoids that people can access the public interface of Header. This was the original intention to have a base class. CanData needs to forward these functions to Header. In the consequece, I would reconsider to use composition instead of inheritance here. But the solution should work.
Solution 2: Header's destructor must be protected, not the base class as a whole.
class Header
{
public:
uint8_t Version() const;
const Timestamp& StartTime();
// ... more simple setters and getters with error checking
protected:
~Header() = default;
private:
uint8_t m_Version;
Timestamp m_StartTime;
};
Then no user can delete Header. This is fine for me, because Header has no purpose on its own. With public derivation, the public interface remains available to the user.
My understanding is that CanData needs not implement a destructor to call the base class's desctructor. All can use the default destructor. I am not completely sure about this though.
All in all, the answers to my questions in the end of the origial positing are:
Is it right that the class hierarchy without the virtual destructor is a problem even if all classes use the compiler's default destructor?
It is only a problem if your destructor is public. You must avoid that people can access you desctrutor, except for derived classes. And you must ensure that derived classes call (implicitely) the base class's destructor.
Is it therefore right that I cannot have a safe class hierarchy that is trivially copyable?
You can make your base class safe with protected inheritance or a protected desctructor. Then you can have a hierarchy of trivially copyable classes.
I'm currently trying to make a pair of classes which depend on each other. Essentially, objects of class B create objects of class A. However, I am also using an inheritance hierarchy, so all derivatives of class B must also be able to create derivatives of class A (each derivative of B corresponds to a derivative of A, so DerB1 makes DerA1 objects, and DerB2 makes DerA2 objects).
I'm having problems with my implementation, and it may be silly, but I would like to see if anyone knows what to do. My code is below (I HATE reading other people's code, so I tried to make it as easy to read as possible...only a few important bits, which I commented to explain)
class BaseB {} // Declare BaseB early to use in BaseA constructor
class BaseA
{
public:
BaseA(BaseB* b) {}; // Declare the BaseA constructor (callable by all B classes, which pass a pointer to themselves to the constructor so the A objects can keep track of their parent)
}
class DerA:public BaseA
{
DerA(BaseB* b):BaseA(b) {}; // Inherit the BaseA constructor, and use initialization list
}
class BaseB
{
public:
virtual BaseA createA() = 0; // Virtual function, representing method to create A objects
}
class DerB:public BaseB
{
BaseA createA() {
DerA* a = new DerA(this); // Definition of createA to make a new A object, specifically one of type DerA (Error1: No instance of constructor "DerA::DerA" matches the argument list)
return a; // Error2: Cannot return DerA for BaseA function
}
}
So, I have two main problems, one is practical (Error1, as I seem to simply be calling the function wrong, even if I try to typecast this), one is philosophical (Error 2, as I don't know how to implement the features I want. If anyone could point out why Error1 is occurring, that would be wonderful! Error2, however, requires some explanation.
I would like my user (programmer) to interact with all A objects the same way. They will have the same exact public functions, but each will have VERY different implementations of these functions. Some will be using different data types (and so will require function contracts), but many will have the same data types just with different algorithms that they use on them. I would like some piece of code to work exactly the same way if one class A derivative is used or another is. However, in my current implementation, it seems that I need to return a DerA object instead of a BaseA object (at the site of Error2). This means that I will need to write a segment of main code SPECIFICALLY for a DerA object, instead of any arbitrary A object. I would like something like:
BaseB b = new DerB(); // Declare which derivative of BaseB I want to use
BaseA a = b->createA(b); // Call the createA function in that derivative, which will automatically make a corresponding A object
This way, I can simply choose which type of B object I would like in the first line (by my choice of B constructor, or tag, or template, or something), and the rest of the code will look the same for any type of object B (as each has the same public member functions, even though each object will perform those functions differently).
Would I be better off using templates or some other method instead of inheritance? (I apologize for being intentionally vague, but I hope my class A/B example should mostly explain what I need).
Thank you for any help. I apologize for asking two questions in one post and for being long-winded, but I am trying to learn the best way to approach a rather large redesign of some software.
You have several syntactical issues to get the errors solved:
Add the ; after each class definitions.
The first line should be a forward declaration: class BaseB /*{} NO!!*/ ;
Add public: to make constructor of DerA accessible for DerB
BaseA createA() should return a value, not a pointner (according to signature): return *a;
There is another potential hidden slicing issue, as createA() returns a value, an not a pointer. This means that your returned object (here *a), would be copied but as a real BaseA object. So only the BaseA part of the object will be copied, not the derived part. This could lead to some unexpected surprises.
In order to avoid slicing, consider returning a pointer, changing the signature of createA() accordingly. The object pointed to would then keep the right type without loosing anything.
If you would later need to copy the object, you could use a static cast if you are absolutely sure of the real type of the object pointed to:
BaseA *pba = pdb->createA(); // get pointer returned
DerA da = *static_cast<DerA*>(pba); // static cast with pointer
If you would need to copy pointed BaseA objects without necessarily knwowing for sure their real type, you could implement a virtual clone function in DerA (e.g. prototype design pattern)
In an existing project, I am to inherit a Controller class (MVC) declared as Singleton so as to define my own treatment. How to appropriately derive this Singleton class?
First, I expand on context and need for this inheritance.
The application that I am added to the existing software wants to use a MVC module that performs almost same task as the one I am willing to perform. It is using the same methods up to signature and slight modifications. Rewriting my own MVC module would definitively be duplication of code. The existing module is intrinsically oriented towards its application to another part of the software, and I cannot simply use the same module. But is written as a Model-View-Controller pattern where Controller is Singleton. I derived View already.
Second, I have doubt that I can classicaly derive Singleton class.
Calling constructor from inherited class would simply call getinstance() for parent class and fail to return an object from derived class (?).
Third, it's how I see some way to deal with. Please comment/help me improve!
I copy the whole Singleton class in a class I could call AbstractController. I derive this class twice. The first child is singleton and adopts the whole treatment of parent class. The second child is the Controller for my part of the application, with own redefined treatment.
Thanks!
Truth is, singletons and inheritance do not play well together.
Yeah, yeah, the Singleton lovers and GoF cult will be all over me for this, saying "well, if you make your constructor protected..." and "you don't have to have a getInstance method on the class, you can put it...", but they're just proving my point. Singletons have to jump through a number of hoops in order to be both a singleton and a base class.
But just to answer the question, say we have a singleton base class. It can even to some degree enforce its singleness through inheritance. (The constructor does one of the few things that can work when it can no longer be private: it throws an exception if another Base already exists.) Say we also have a class Derived that inherits from Base. Since we're allowing inheritance, let's also say there can be any number of other subclasses of Base, that may or may not inherit from Derived.
But there's a problem -- the very one you're either already running into, or will soon. If we call Base::getInstance without having constructed an object already, we'll get a null pointer. We'd like to get back whatever singleton object exists (it may be a Base, and/or a Derived, and/or an Other). But it's hard to do so and still follow all the rules, cause there are only a couple of ways to do so -- and all of them have some drawbacks.
We could just create a Base and return it. Screw Derived and Other. End result: Base::getInstance() always returns exactly a Base. The child classes never get to play. Kinda defeats the purpose, IMO.
We could put a getInstance of our own in our derived class, and have the caller say Derived::getInstance() if they specifically want a Derived. This significantly increases coupling (because a caller now has to know to specifically request a Derived, and ends up tying itself to that implementation).
We could do a variant of that last one -- but instead of getting the instance, the function just creates one. (While we're at it, let's rename the function to initInstance, since we don't particularly care what it gets -- we're just calling it so that it creates a new Derived and sets that as the One True Instance.)
So (barring any oddness unaccounted for yet), it works out kinda like this...
class Base {
static Base * theOneTrueInstance;
public:
static Base & getInstance() {
if (!theOneTrueInstance) initInstance();
return *theOneTrueInstance;
}
static void initInstance() { new Base; }
protected:
Base() {
if (theOneTrueInstance) throw std::logic_error("Instance already exists");
theOneTrueInstance = this;
}
virtual ~Base() { } // so random strangers can't delete me
};
Base* Base::theOneTrueInstance = 0;
class Derived : public Base {
public:
static void initInstance() {
new Derived; // Derived() calls Base(), which sets this as "the instance"
}
protected:
Derived() { } // so we can't be instantiated by outsiders
~Derived() { } // so random strangers can't delete me
};
And in your init code, you say Base::initInstance(); or Derived::initInstance();, depending on which type you want the singleton to be. You'll have to cast the return value from Base::getInstance() in order to use any Derived-specific functions, of course, but without casting you can use any functions defined by Base, including virtual functions overridden by Derived.
Note that this way of doing it also has a number of drawbacks of its own, though:
It puts most of the burden of enforcing singleness on the base class. If the base doesn't have this or similar functionality, and you can't change it, you're kinda screwed.
The base class can't take all of the responsibility, though -- each class needs to declare a protected destructor, or someone could come along and delete the one instance after casting it (in)appropriately, and the whole thing goes to hell. What's worse, this can't be enforced by the compiler.
Because we're using protected destructors to prevent some random schmuck from deleting our instance, unless the compiler's smarter than i fear it is, even the runtime won't be able to properly delete your instance when the program ends. Bye bye, RAII...hello "memory leak detected" warnings. (Of course the memory will eventually be reclaimed by any decent OS. But if the destructor doesn't run, you can't depend on it to do cleanup for you. You'll need to call a cleanup function of some sort before you exit, and that won't give you anywhere near the same assurances that RAII can give you.)
It exposes an initInstance method that, IMO, doesn't really belong in an API everyone can see. If you wanted, you could make initInstance private and let your init function be a friend, but then your class is making assumptions about code outside itself, and the coupling thing comes back into play.
Also note that the code above is not at all thread safe. If you need that, you're on your own.
Seriously, the less painful route is to forget trying to enforce singleness. The least complicated way to ensure that there's only one instance is to only create one. If you need to use it multiple places, consider dependency injection. (The non-framework version of that amounts to "pass the object to stuff that needs it". :P ) I went and designed the above stuff just to try and prove myself wrong about singletons and inheritance, and just reaffirmed to myself how evil the combination is. I wouldn't recommend ever actually doing it in real code.
I'm not sure I understand the situation you're dealing with fully, and whether or not it's possible or appropriate to derive from the singleton depends very much on how the singleton is implemented.
But since you mentioned "good practice" there's some general points that come to mind when reading the question:
Inheritance isn't usually the best tool to achieve code re-use. See: Prefer composition over inheritance?
Using singleton and "good practice" generally do not go together! See: What is so bad about singletons?
Hope that helps.
I recently had the similar need in my app... in any case here is my out of code implementation :
h.
class icProjectManagerHandler;
class icProjectManager : public bs::icBaseManager {
friend class icProjectManagerHandler;
protected:
icProjectManager();
public:
~icProjectManager();
template<typename t>
static t *PM() {
return dynamic_cast<t *>(icProjectManagerHandler::PMH()->mCurrentManager);
};
template<typename t>
static t *PMS() {
static icProjectManagerHandler pm;
return static_cast<t *>(icProjectManagerHandler::PMH()->mCurrentManager);
};
};
class icProjectManagerHandler {
friend class icProjectManager;
icProjectManager *mCurrentManager;
icProjectManagerHandler();
public:
~icProjectManagerHandler();
static icProjectManagerHandler *PMH();
inline void setProjectManager(icProjectManager *pm) {
if (mCurrentManager) { delete mCurrentManager; }
mCurrentManager = pm;
}
};
Cpp.
icProjectManagerHandler::icProjectManagerHandler() {
mCurrentManager = new icProjectManager();
}
icProjectManagerHandler::~icProjectManagerHandler() {
}
icProjectManagerHandler *icProjectManagerHandler::PMH() {
static icProjectManagerHandler pmh;
return &pmh;
}
icProjectManager::icProjectManager() {
}
icProjectManager::~icProjectManager() {
}
And example:
class icProjectX : public ic::project::icProjectManager {
public:
icProjectX() {};
~icProjectX() {};
};
int main(int argc, char *argv[]) {
auto pro = new icProjectX();
pro->setIcName("Hello");
ic::project::icProjectManagerHandler::PMH()->setProjectManager(pro);
qDebug() << "\n" << pro << "\n" << ic::project::icProjectManager::PMS<icProjectX>();
return 10;
}
The issue of this implementation is that you have to initialize your "singleton" class 1st or else you will get the default base class. But other than that... it should work?
Consider the following code:
class Base {
protected:
int* ptr_;
public:
virtual ~Base() { /* delete ptr_ ?? */ }
}
class A : public Base {
public:
A() { ptr_ = new int; }
~A() { /* delete ptr_ ?? */ }
}
I'm having a minor dispute with my colleague.
Which destructor should delete ptr_?
I think it should be in A, because it's where it is allocated.
He thinks it should be in Base, because thats where the pointer is.
Please give possible pitfalls why one method is better than the other (if there is one, and it's not just a matter of taste)
EDIT
Alot of people are questioning the design. In practice, the code is much more complicated, and models an Image processing system involving a few cameras.
The role of Base is to manage the resources of the system (A few configurations exist).
Class A and other derived types like it decide the configuration of Base and initialize the system to a specific configuration. I guess now you can ask if Inheritance is the right choice over Composition. A is-a Base, just a specific kind, and that is why we chose inheritance. In this case, ptr_ is a pointer to a specific driver of a camera, which will be decided by the derived type, that is why it is allocated there.
Each class should manage its own resources. When you have multiple derived classes, each one must remember to free the pointer. This is bad, since it duplicates code.
If some derived class is allowed not to assign the pointer a fresh value, then set it to zero in the base class constructor. If some derived class should be allowed to assign to the pointer the address of an automatic variable, then review your design.
Use smart pointers to make the problem totally go away (when I grep delete * in my entire codebase, I find no match :)
The question is one of design more than one of implementation. I tend to agree with your coworker, if the pointer is in the base, it seems to indicate that the base object is responsible for management of the resource, rather than the derived type.
As a matter of fact the bit that is strange is the fact that the derived constructor is modifying a base member, it probably makes more sense to pass the pointer to the base constructor in which case the semantics would be clearer: the base receives a resource during construction and is responsible to manage it during it's lifetime.
If the base should not manage the resource, then why is the pointer at that level? Why is it not a member of the derived type?
Note that when managing a resource, you should consider the rule of the three1: If you have to implement one of copy-constructor, assignment-operator or destructor, then you probably want to implement the three of them (additionally consider implementing a no-throw swap which will be handy).
Once you add copy-constructor and assignment-operator to the mix you will probably see that the natural place to manage the resource is there where it is held.
1 The rule is generic as there are good reasons not to implement all of them always. For example, if you manage your resources inside members that implement RAII (as smart pointers), you might need to provide copy-construction and assignment-operator's as for deep copying semantics, but destruction would not be required. Alternatively, in some contexts you might want to disable *copy-construction* and/or assignments.
In fact, ptr_ should be private! (See Scott Meyers Effective C++, or any primer on object orientation.)
Now, the question doesn’t even pose itself: only the base class can manage its resource. The derived class can only initialise it by passing a request forward to its base (preferably via the constructor):
A() : Base(new int()) { }
I would prefer deleting it in the Base class because,
If I deallocate it in Derived class destructor(which gets called before Base class destructor) then there is a chance that it can get used accidentally in Base class.
Also, The lifetime of the pointer ends within Base class so that should be the place to deallocate it. In fact, I would allocate the pointer within the Base class and not Derived class.
Best is ofcourse to use RAII, and not delte the pointer explicitly, let the Smart pointers take care of deallocating themselves.
You're worrying about code duplication, but I am afraid it clouded your judgement.
I know that DRY get a lot of press (and for good reason) but you misunderstood it. There is a difference between not duplicating code and not duplicating functionality.
DRY is about not duplicating functionality. There might be code patterns that look alike, but are used for different goals, those should not be merged as each goal could shift independently (and un-merging is a nightmare). Their ressemblance is coincidental.
This is the case here. You arbitrarily force a int* ptr_ in the Base (which does not use it) class because surely all derived classes will need it. How do you know that ? At the moment it turns out that all derived classes do need it, but this is a coincidence. They could choose to rely on something else.
Therefore, a sane design is to provide an interface in the base class, and leave it up to each derived class to choose its own implementation:
class Base { public: virtual ~Base() {} };
class D1: public Base {
public:
D1(Foo const& f): ptr_(new Foo(f)) {}
private:
std::unique_ptr<Foo> ptr_;
};
class D2: public Base {
public:
D2(Bar const& f): ptr_(new Bar(f)) {}
private:
std::unique_ptr<Bar> ptr_;
};
On the other hand, if the Base class was to provide some common functionality that required data members, then of course those could be hoisted up in the Base class implementation... though it could be argued this is premature optimization as, once again, some derived classes might choose to do things differently.
ptr_ shouldn't be in the base class because nothing in the base class uses it. It should be in the derived class.
If you must have it there, I agree with you, it should be deleted in the derived classes desteuctor. The base class can't even know if that pointer was even used, why should it delete it?
The best practice is the object that creates the resource should delete the resource - it is their responsibility.
To me the best is to have the same object in charge of the allocation and the unallocation.
So in your code, class A would be in charge of the delete as it performed the new.
But: why did A allocate ptr_ instead of Base? This is the real question here. There's a problem of design to me as ptr_ belongs to Base. Either it should belong to A instead, or Base should be in charge of its memory management.
i would do this, using RAII.
class RaiiResource
{
private:
int* ptr_;
public:
RaiiResource() { ptr_ = new int; }
~RaiiResource() { delete ptr_; }
int* getResource() { return ptr_; }
}
class Base
{
protected:
RaiiResource m_raiiresource;
void anyMethod()
{
int* pIntNeeded = m_raiiresource.getResource();/*when you need the resource*/
}
public:
virtual ~Base() {}
}
class A : public Base {
public:
A() {}
~A() { }
void anyOtherMethod()
{
int* pIntNeededAgain = m_raiiresource.getResource(); /*when you need the resource again somewhereelse*/
}
}
Another way would be using std::shared_ptr that allows managing the scope of life of objects between different objects, which is the case in your case ( Base and A are sharing the need of the object (int) existence)