I have a question about style. I have a class (in my case an Option) that depends on the value of an exogenous object (Interest Rate). My goal is to create a abstract base class for the exogenous object (Rate) so that I can construct variations, say SimulatedRate or ConstantRate, that will work inside my depending class, Option.
However, I'm finding in C++, since I obviously cannot instantiate a abstract base class, I must store either a pointer or a reference to the base class. My concern is that when the instantiated exogenous objects go out of scope outside of the dependent class, my dependent class will be pointing to junk.
Is there a reasonable way to utilize polymorphism for this problem in C++?
My current code:
class Dependent
{
public:
Dependent(const Exogenous& exo) : exo_(exo) {}
double getSomething() const { exo_.interfaceMethod(); }
private:
Exogenous& exo_;
}
class Exogenous
{
public:
virtual double interfaceMethod() const=0;
}
class ExogenousVariationA
{
public:
virtual double interfaceMethod() const { return resultA; }
}
class ExogenousVariationB
{
public:
virtual double interfaceMethod() const { return resultB; }
}
Your worry is valid. Since you are storing to a reference an object passed in by the client, you are trusting that client to keep the object alive while you need it. This can easily lead to problems. Of course, the same would be true if you used raw pointers to dynamically allocated objects. If the client does delete on the object before you're done with it, once again you have a problem.
The solution is to force the client to give you some kind of responsibility over the lifetime of the object. The way to do this is to ask for a smart pointer. Depending on your problem, you may want a std::unique_ptr or std::shared_ptr. Use the former if you want to take ownership from the client or the latter if you want to share ownership with them. Let's say you choose std::unique_ptr, you would then define your Dependent class as:
class Dependent
{
public:
Dependent(std::unique_ptr<Exogenous> exo) : exo_(std::move(exo)) {}
double getSomething() const { exo_->interfaceMethod(); }
private:
std::unique_ptr<Exogenous> exo_;
}
The client would use this like so:
std::unique_ptr<Exogenous> ptr(new ExogenousVariationA());
Dependent dep(std::move(ptr));
Now, when your client passes the std::unique_ptr to you, they're giving you ownership of the object. The object will only be destroyed when your std::unique_ptr is destroyed (which will be when your Dependent is destroyed, since it is a member).
Alternatively, if you take a std::shared_ptr then the object will be destroyed once both the client's and your std::shared_ptrs are destroyed.
sftrabbit has some good advice, to which I'd add:
you could create a virtual clone() method in the abstract base class (it's not a virtual base class - that's something else entirely); that method would be implemented in the derived interest rate classes, returning a pointer to a new independent interest rate object that can be owned by the Option; this is particularly useful if the objects contain data that changes as you use it (e.g. from calculations or caching)
you probably don't want this, but with std/boost shared pointers it's also possible to ask for a weak pointer to the shared object... that way you can test whether the "owners" of the object (which won't include you) have already finished with it and triggered its destruction
Separately, to use runtime polymorphism your ExogenousVariationA and ~B classes must actually derive from Exogenous, and the method you want to be polymorphically dispatched must be virtual. That looks like this:
class Exogenous
{
public:
virtual double interfaceMethod() const=0;
}
class ExogenousVariationA : public Exogenous
{
public:
double interfaceMethod() const { return resultA; }
}
Related
Let's assume we have interface selector_interface_t and implementation of this interface pin_selector_t.
class selector_interface_t
{
public:
virtual void select(uint8_t address) = 0;
virtual void deselect() = 0;
};
class pin_selector_t : public selector_interface_t
{
private:
uint8_t mask;
public:
pin_selector_t(uint8_t mask);
void select(uint8_t address);
void deselect();
};
And now we want to pass object witch implements this interface to class myclass_t and store for future use by other myclass_t methods (eg. strobe).
class myclass_t
{
private:
selector_interface_t * selector;
public:
myclass_t(selector_interface_t & selector);
void strobe(uint8_t pin);
};
myclass_t::myclass_t(selector_interface_t & selector) // : selector(selector)
{
// ...
}
void myclass_t::strobe(uint8_t pin)
{
this->selector->select(pin);
this->selector->deselect();
}
The only way is pass implementation by pointer or by reference. I prefer second solution and pass by reference. But I cannot simply store this reference in myclass_t object because of lifetime of object with interface implementation. It would be better to make a copy. But I cannot have selector_interface_t field member. I can only have reference or pointer to this type. On the other way I'd like to avoid using malloc. What can I do with it?
If you are the one who creates the selector_interface_t type then you can store it inside a shared_ptr and have the myclass_t class hold a weak_ptr or shared_ptr to the interface.
If you are not the one who creates selector_interface_t then I assume you have other means of keeping the object alive, wrap it in a class that manages the lifetime and that object wrap in shared_ptr.
If you can't guarantee that the implementation has the right lifetime, then you need to manage it, which means dynamically allocating it. (Using new, not malloc.)
I would strongly suggest using either shared_ptr<selector_interface_t> or unique_ptr<selector_interface_t> - depending on whether or not you ever want to share implementation objects between clients. You then get correct code with very little effort.
A situation I often come up against is having a set of classes, Base and Derived, where the Base class has ownership of a base-class member BaseMember, and the Derived class has a reference or pointer to the same object, but as a DerivedMember.
For example, a UI panel class that contains a specific instance of a certain type of control with some special-control functions, inheriting from a general class that contains a general control and has general-control functions.
First, say that BaseMember is inherited by DerivedMemeber.
Without using smart pointers, I might do something like this:
class Base
{
protected:
// receive ownership but only because we say so,
// someone else can still try to delete as it's "just a pointer"
Base(BaseMember* _bmember):
bmember(_bmember)
{}
public:
virtual ~Base()
{
// perform an owner's duty
delete bmember;
}
// functions that might be based on BaseMember + other base state
void SetMemberId(....)
{
bmember->SetId(baz);
}
private:
int baz;
BaseMember* bmember; //owned, but not smartly
}
class Derived: public Base
{
public:
Derived(DerivedMember* _dmember):
Base(_dmember),
dmember(_dmember)
{}
// functions that only make sense for Derived + Derived/Base state
void SetDerivedFrobulation()
{
// only a DerivedMember has frobulation, so only
// Derived allows users to access it
dmember->setFrobulation(foo);
}
private:
int foo; // some state
DerivedMember* dmember; // no ownership here
}
With smart pointers (C++11 and up, specifically, I don't really care about older C++ in this case), I am tempted to do something like this and never let the Base/DerivedMember object out into dumb-pointer-land where it could leak if there was an exception somewhere inconvenient.
class Base
{
protected:
// receive ownership
Base(std::unique_ptr<BaseMember> _member):
member(std::move(_member))
{}
virtual ~Base()
{}
public:
// public access functions here as before
private:
std::unique_ptr<BaseMember> member;
}
class Derived: public Base
{
public:
// pass the ownership down by unique_ptr
Derived(std::unique_ptr<DerivedMember> _dmember):
Base(std::move(_dmember)),
dmember(_dmember.get()) // _dmember is moved! SEGFAULT if access dmember later!
{}
// public access functions here as before
private:
// handy handle to the derived class so we don't need to downcast the base (or even access it!)
DerivedClass* dmember
}
As I noted there, you can't "steal a peek" at the DerivedMember class as it comes in to the Derived constructor, because the unique_ptr is moved away before Derived gets a look in.
I can see a solution in providing a protected access to the BaseMember and static_casting back to DerivedMember in the Derived constructor (i.e. after the Base constructor is done), but this seems an ugly way to get access back to a variable we let slip though our fingers!
Another way could be each inheritor of Base owns the pointer, and base just gets a dumb pointer. In this case, the Base destructor doesn't get access to the member, as it's already gone. Also it would duplicate the ownership logic needlessly.
I think either:
This is symptomatic of an anti-pattern and the design of the whole Base/Derived/BaseMember/DerivedMember system is not good practice.
I'm missing a trick and there is a clean way to do this without fumbling a smart pointer and making a leak possible or adding functions and exposing interfaces or casting too much.
Is this a good pattern for re-use, or should I look elsewhere?
Expanding on the use case (EDIT)
In a core library, I have a class DataInterpreter which shows "some interpretation" of data - could be a string, an image, etc. This is then inherited by, amongst others, TextInterpreter which presents a string.
I then have a DataDisplayPanel class which represents a piece of UI for displaying in an abstract sense. Exactly what is in this panel will depend on the interpreter used: a TextInterpreter should get a text entry field and say a button to set some text display option, and that is handled in TextDisplayPanel, which has "special" knowledge of the text aspect of the interpreter.
There is then a DataAggregatePanel which combines a number of DataDisplayPanels and provides some global settings that affect all displays (via virtual functions), and manages the panels in a std::vector<std::unique_ptr<DataDisplayPanel> >. This aggregate class doesn't deal with any of the derived classes at all, any functions would be polymorphic and defined in the base.
In the application (which depends on the core library), these classes are extended (by inheritance or composition, whichever makes more sense). For example, if the application is a WX GUI, I might have wxDataAggregatePanel which contains wxTextDisplayPanel (and others), all of which are wxPanels. In this case, wxTextDisplayPanel might own a wxTextEntry and either own or inherit TextInterpreter and use its knowledge of the TextInterpreter's specific methods to fill the text box with a string.
You may use delegating constructor:
class Derived: public Base
{
public:
Derived(std::unique_ptr<DerivedMember> _dmember):
Derived(_dmember, _dmember.get())
{}
// public access functions here as before
private:
Derived(std::unique_ptr<DerivedMember>& _dmember, DerivedMember* ptr):
Base(std::move(_dmember)),
dmember(ptr)
{}
private:
// handy handle to the derived class so we don't need to downcast the base (or even access it!)
DerivedClass* dmember
};
I have got problem with passing inherited class type as argument to method that takes its base class type.
class Base {...}
class Derived : public Base {...}
class Container {
vector<Base*> cont; //1
public:
void addToCont(Base x) { //2
cont.push_back(&x);
}
}
int main() {
Container c;
c.addToCont(Derived(p1,p2)); //3
}
1) I suppose I need to have container of pointers to objects to keep it working
2) Here is error in conversion from Derived to Base
3) I am not supposed to change this call. I tried
Derived d(p1,p2);
c.addToCont(d);
with
addToCont(Base& x)
and it worked for me.
My problem is that I've got 3 derived classes and I don't want to overload the add method 3 times. I guess I will have to add some virtual method or some type-casting to those classes, but I couldn't find anything about that. I am novice in inheritance and quite confused of this. Thanks for all your help.
Some notes:
Must use a vector of pointers to the Base, so that you can handle objects from the hierarchy. Goes without saying that you're probably better off with using some kind of smart pointer instead of raw pointers, but that goes in preferences and how much you love risk.
Using void addToCont(Base x) is wrong because even if you were only adding a Base object, you will be adding a pointer to a local variable (the pass-by-value parameter)
Using void addToCont(Base &x) the way you do it with a local Derived d is wrong too, for the same reasons as before, as soon as d goes out of scope, you're left with a dangling pointer stored in the pointer
Calling addToCont(Derived(...)) passes a temporary object. That must be taken into account when you think about your memory management.
Not sure why you see a need for overloading addToCont for all Derived classes, that's not what you did on void addToCont(Base &x)
The solution (if you keep to the raw pointers) is to do void addToCont(Base *x) there you can pass a pointer to Base or to any Derived. Again, you must be mindful about the memory management. You're Derived object probably needs to be allocated with a new Derived(...) and you must watch about who owns it, and who has responsibility for deleting it (for example, when the Container object is destroyed).
You probably should remember to make virtual the destructor of Base, because you will be destroying Derived objects from Base pointers, and if the destructor is not virtual, the object will only be partially destroyed.
If addToCont(Derived(...)) call is absolutely required, then you might want to consider to use the void addToCont(Base &x) defininition.... but them, you must clone the object before inserting it into the vector:
void addToCont(const Base &x) { //2
cont.push_back(x.clone());
}
But then.. you need a virtual Base *clone() const method to be implemented (at least) in the Derived classes, that will produce a Base pointer with an exact copy of the Derived object, involving extra copies of the objects and extra cloning...
Derived classes are only "possible to use" when they are either references or pointers. If you convert a class to a base-class without a reference or pointer, you won't be able to use it as a derived class later.
If you are actually storing pointers in your container, then I would make it explicit, so:
class Container {
vector<Base*> cont;
public:
void addToCont(Base* x) {
cont.push_back(x);
}
~Container()
{
for(auto a : cont)
{
delete a;
}
}
}
And in main:
Container c;
c.addToCont(new Derived(p1,p2));
Note that in your original code, the Derived(p1, p2) will get destroyed again just after call to addToCont(...), so your array would be pointing to a "dead" element of the Derived class. Which was probably not what you actually wanted (since it's undefined behaviour to ever use that element, and building up a container full of useless elements is pretty pointless)
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)
I've been looking at the example C++ Factory method pattern at Wikipedia and have a couple of questions:
Since the factory method is static, does that mean the newly created object won't go out of scope and have the destructor method called when the factory method exits?
Why return a pointer, as opposed to a reference? Is it strictly a matter of preference, or is the some important reason for this?
Edit 1: The more I think about it, both the reference and the pointer returned will stay in scope because they are referenced outside of the method. Therefore, the destructor won't be called on either one. So it's a matter of preference. No?
Edit 2: I printed out the destructor call on the returned reference, and it doesn't print until the program exits. So, barring further feedback, I'm going to go with the reference for now. Just so I can use the "." operator on the returned object.
Static method is one that can be called without having an instance of the factory. That has nothing to deal wtih the lifetime of the newly created object. You could use a non-static method with the same success. The factory method usually doesn't need any data from an existing object of the same class and therefor doesn't need an existing instance and this is why factorey methods are usually static.
You will use new to create the object that the factory will return. It's usual to return them by pointer. This shows explicitly that it's a new object ant the caller must take care of its lifetime.
I'm thinking there is a greater issue of understanding memory management. The factory method is allocating items on the heap (using new). Items on the heap never get automatically reclaimed (except by modern desktop OSs on process termination). The behavior you are describing is for items on the stack where they are reclaimed when you leave the local scope.
If you return a reference to an object that reference will become invalid when the method goes out of scope. This won't happen with a pointer, since the destructor isn't called.
It is true that static modifies when the value goes out of scope, but only if the variable is declared static, not if the method is declared static.
Your Wiki link says wrong.
There shouldn't be any static method. You can consider Factory Method as Template Method pattern that creates Objects. This method doesn't receive any "Name" parameter and create all the time same type of object.
Often, designs start out using Factory
Method (less complicated, more
customizable, subclasses proliferate)
and evolve toward Abstract Factory,
Prototype, or Builder (more flexible,
more complex) as the designer
discovers where more flexibility is
needed. [GoF, p136]
In the following example Business::makeObject is the factory method
class ObjectBase
{
public:
virtual void action() = 0;
virtual ~ObjectBase(){};
};
class ObjectFirst : public ObjectBase
{
public:
virtual void action(){ std::cout << "First"; }
};
class ObjectSecond : public ObjectBase
{
public:
virtual void action(){ std::cout << "Second"; }
};
class Business
{
public:
void SendReport()
{
std::auto_ptr< ObjectBase > object(makeObject());
object->action();
}
virtual ~Business() { }
protected:
virtual ObjectBase* makeObject() = 0;
};
class BusinessOne: public Business
{
public:
protected:
virtual ObjectBase* makeObject()
{
return new ObjectFirst();
}
};
class BusinessTwo: public Business
{
public:
protected:
virtual ObjectBase* makeObject()
{
return new ObjectSecond();
}
};
int main()
{
std::auto_ptr<Business> business( new BusinessTwo() );
business->SendReport();
return 0;
}
No. Static method - is almost same as global function in class namesapce and with access to private static variables;
Pointers usage is issue of createing objects in heap. They create object in heap for longer object lifetime than create-function scope;
EDIT:
I think wikipedia - is wrong in c++ example.
We have in exmaple - not same implementation as in class diagram or here (http://www.apwebco.com/gofpatterns/creational/FactoryMethod.html)
It will be better if you read about patterns from most trusted sources, e.g: Design Patterns: Elements of Reusable Object-Oriented Software.
The keyword static means different things on a method and on a variable. On a method as in the example it means that it is class global, and you need not have an instance of the class to call it.
To create a new object dynamically you need to use new, or 'a trick' is to assign a temporary object to a reference. assigning a temporary object to a point will not keep that object alive.
So you could do the following, but it is not normally done because you would often want to keep many things created from a factory, and then you would have to copy them rather than simply holding the pointer in a list.
class PizzaFactory {
public:
static Pizza& create_pizza(const std::string& type) {
if (type == "Ham and Mushroom")
return HamAndMushroomPizza();
else if (type == "Hawaiian")
return HawaiianPizza();
else
return DeluxePizza();
}
};
const Pizza &one = create_pizza(""); // by ref
Pizza two = create_pizza(""); // copied
EDIT
Sorry mistake in code - added missing const to ref.
Normally, a temporary object lasts only until the end of the full expression in which it appears. However, C++ deliberately specifies that binding a temporary object to a reference to const on the stack lengthens the lifetime of the temporary to the lifetime of the reference itself