Shared pointer inheritance without explicitly casting first - c++

So, I am trying to do something like this
template <typename T>
void call(std::shared_ptr<Base<T>> b) {
}
int main() {
std::shared_ptr<Derived<int>> d = std::make_shared<Derived<int>>();
call(d);
}
It cant resolve the inheritance because they are shared pointers. Ideally I don't want to use static_pointer_cast or something like that in main so I was looking for maybe a different way to cast it so that the user in main can still call the same function but not have to worry about casting.
My second approach was to use raw pointers so I tried something like this:
template <typename T>
void call(Base<T> * b) {
std::shared_ptr<Base<T>> obj(b);
}
int main() {
std::shared_ptr<Derived<int>> d = std::make_shared<Derived<int>>();
call(d.get());
}
Since Base is an abstract class I can't use make_shared so I have to do it this way to my knowledge but the problem then becomes that as soon as the call function's scope ends it deletes the pointer resulting in a double free error since the shared ptr in main also tries to delete this.
Are there any suggestions for something to try?

First, it is a bad practice to use smart pointers wherever the ownership is not needed. In your case the main function owns the pointer, and there is no way the object is destroyed while the call function is being executed. So you may pass a raw pointer without problems (and that is even better because the interface doesn't require more than it needs). This however may not be true in case of multithreaded environment or if the call function has side effects storing the pointer (e.g. that is actually a set method if a class). In this case shared_ptr should be used indeed.
Next, you may create a shared_ptr<Base> initializing it with a pointer to Derived. You even don't need to have virtual destructor for deleting the object: shared_ptr knows the actual type:
{
std::shared_ptr<Base> d = std::make_shared<Derived>();
// Ok to delete
}
Finally, there is no problem in casting shared_ptr<Derived> to shared_ptr<Base>. That is another instance of a shared pointer that points to the same counter.

Related

Conditional declaration of objects inherting from a common base class to pass a reference to one of them

Say I have two classes inheriting from a common base, such as
class Thing{
public:
virtual void f()=0;
};
class Thing_variant_a: public Thing{
public:
void f(){
std::cout<<"I am (a)"<<std::endl;
}
};
class Thing_variant_b: public Thing{
public:
void f(){
std::cout<<"I am (b)"<<std::endl;
}
};
And a function taking a reference to a Thing object as an argument.
void function(Thing& t){
t.f();
}
Depending on conditions I would like to call function with either a thing_a or thing_b (and possibly extend this at some point adding another possibility of thing_c)
I know I can do this using a pointer
Thing *t = nullptr;
if(condition_a){
t = new Thing_variant_a();
} else if(condition_b){
t = new Thing_variant_b();
}
function(*t);
However, I would like to know if there is a better way, that
does not allocate heap memory
does not require me to take care of deleting t at some point (probably smart pointers, but I don't know much about those)
ensures I always pass a valid Thing reference to function (there might be more conditionals in a complicated structure than in this minimal example) I could do if(t){ function(*t);}else{/*handle error*/}), but it seems like there should be a more elegant solution.
If not all of the above are possible any combination of those?
This sounds very much like an XY problem. There is probably a different solution to your problem entirely.
C++ is a statically-typed language; that means types used in a given code path are fixed at compile-time. Dynamic types (types known at run time) are normally allocated via the heap or all-at-once and then selected at run time.
So not much is possible in your case as you've noticed..
You could for example just have two different code paths:
if (condition_a) {
Thing_variant_a a;
function(a);
} else if (condition_b) {
Thing_variant_a b;
function(b);
}
Preallocate the types:
Thing_variant_a a;
Thing_variant_a b;
if (condition_a) {
function(a);
} else if (condition_b) {
function(b);
}
Or use a template:
template<typename T>
void do_something() {
T t;
function(t);
}
// somewhere else in the code ...
do_something<Thing_variant_a>();
// or ...
do_something<Thing_variant_b>();
Here's a way using dynamic memory and unique_ptr:
std::unique_ptr<Thing> t;
if (condition_a) {
t = std::make_unique<Thing_variant_a>();
} else if (condition_b) {
t = std::make_unique<Thing_variant_b>();
}
function(*t);
// t is delete'd automatically at end of scope...
And by the way, a function like int f(){...} should return some int value.
Here is a way to do it without using the heap or pointers:
Thing_variant_a thingA;
Thing_variant_b thingB;
if(condition_a){
function(thingA);
} else if(condition_b){
function(thingB);
}
If you want, you reduce it to a single call via the ternary operator:
Thing_variant_a thingA;
Thing_variant_b thingB;
function(condition_a ? static_cast<Thing &>(thingA) : static_cast<Thing &>(thingB));
As far as references go, references in C++ are required to be always be non-NULL -- so if you try to dereference a NULL pointer (e.g. by calling function(*t) when t==NULL) you've already invoked undefined behavior and are doomed; there is nothing the code inside function() can do to save you. So if there is any change that your pointer is NULL, you must check for that before dereferencing it.
I'll try to answer each of your questions
does not allocate heap memory
Unfortunately c++ only supports polymorphism using pointers. I guess the problem you would face here is fragmented memory (meaning that your pointers are everywhere in the heap). The best way to handle that is to allocate the memory using a memory pool.
You could use an std::variant but you will still need to test for the currently available type in the variant.
does not require me to take care of deleting t at some point (probably smart pointers, but I don't know much about those)
You could use a std::unique_ptr which will basically called the destructor when no one holds that pointer anymore.
ensures I always pass a valid Thing reference to function (there might be more conditionals in a complicated structure than in this minimal example) I could do if(t){ function(*t);}else{/handle error/}), but it seems like there should be a more elegant solution.
If you use pointers your could just check for the nullptr as you are doing right now. I'm not sure what you are meaning by valid reference as a reference always points toward something and cannot be empty.

What is best pointer/reference type when returning member possibly allocated on the stack in C++?

So to illustrate my question I have made an example:
#include <iostream>
using namespace std;
struct A
{
void doSomething (){
cout << "Something\n";
}
};
struct B
{
A a;
A *getA ()
{
return &a;
}
};
int
main ()
{
B *b = new B ();
A *a = b->getA ();
// POINT 1
if (nullptr != a)
{
a->doSomething ();
}
delete b;
b = nullptr;
// POINT 2
if (nullptr != a)
{
a->doSomething ();
}
return 0;
}
This compiles and runs without errors on my machine, but if you inspect the code, really there is a problem of a dangling pointer on the lines following the comment marked "POINT 2".
Since b was deleted, then a is now invalid (since it was deleted by dtor of b).
So I could use a shared pointer to remedy this, but that would keep the instance of a around even after b was deleted, and also I would not be able to allocate a on the stack. These are two things I want to avoid. Instead I simply want to know if a is still valid.
I could also have used a unique pointer but then I could only have one single instance of a which is not what I want either, I want many copies of the pointer to a.
So is there some existing pointer/reference type that would allow me to do this? Are there any reason why this is a good/bad idea?
You have just discovered the wonders of ownership semantics :)
How to solve this problem depends on the design of your application: what you need and what you are trying to achieve.
In this case, if you really want to share ownership of an object, use std::shared_ptr which keeps a reference count of how many pointers are left, so that the last deletes the object; possibly std::weak_ptr if you only need to check if the object is still alive but don't want to keep it alive longer than needed.
However, do note that (ab)using shared pointers may be a sign of a bad design.
By the way, your A a; member is not allocated in the stack (i.e. the title is wrong).
Only viable solution using standard library that come in mind is to use std::weak_ptr() - it will allow to check object validity without holding it's ownership. That comes with price - you have to maintain ownership of it with std::shared_ptr. Though it is possible to create std::shared_ptr to an object with automatic storage duration and noop deleter I would do that only if I really need that as such method is error prone and defeats the purpose of a smart pointer.
The best way is to not expose a.
Your B is the interface. Give it the functions you need to perform. Have it go on to invoke whatever it needs to invoke on the a in order to make that happen.
Then remove getA(), and make a private.
Now it's completely encapsulated and the calling scope cannot arse around with it like this!
No need for pointers or dynamic allocation; just good, old-fashioned OOP.

unique_ptr and polymorphism

I have some code that currently uses raw pointers, and I want to change to smart pointers. This helps cleanup the code in various ways. Anyway, I have factory methods that return objects and its the caller's responsibility to manager them. Ownership isn't shared and so I figure unique_ptr would be suitable. The objects I return generally all derive from a single base class, Object.
For example,
class Object { ... };
class Number : public Object { ... };
class String : public Object { ... };
std::unique_ptr<Number> State::NewNumber(double value)
{
return std::unique_ptr<Number>(new Number(this, value));
}
std::unique_ptr<String> State::NewString(const char* value)
{
return std::unique_ptr<String>(new String(this, value));
}
The objects returned quite often need to be passed to another function, which operates on objects of type Object (the base class). Without any smart pointers the code is like this.
void Push(const Object* object) { ... } // push simply pushes the value contained by object onto a stack, which makes a copy of the value
Number* number = NewNumber(5);
Push(number);
When converting this code to use unique_ptrs I've run into issues with polymorphism. Initially I decided to simply change the definition of Push to use unique_ptrs too, but this generates compile errors when trying to use derived types. I could allocate objects as the base type, like
std::unique_ptr<Object> number = NewNumber(5);
and pass those to Push - which of course works. However I often need to call methods on the derived type. In the end I decided to make Push operate on a pointer to the object stored by the unique_ptr.
void Push(const Object* object) { ... }
std::unique_ptr<Object> number = NewNumber(5);
Push(number.get());
Now, to the reason for posting. I'm wanting to know if this is the normal way to solve the problem I had? Is it better to have Push operate on the unique_ptr vs the object itself? If so how does one solve the polymorphism issues? I would assume that simply casting the ptrs wouldn't work. Is it common to need to get the underlying pointer from a smart pointer?
Thanks, sorry if the question isn't clear (just let me know).
edit: I think my Push function was a bit ambiguous. It makes a copy of the underlying value and doesn't actually modify, nor store, the input object.
Initially I decided to simply change the definition of Push to use
unique_ptrs too, but this generates compile errors when trying to use
derived types.
You likely did not correctly deal with uniqueness.
void push(std::unique_ptr<int>);
int main() {
std::unique_ptr<int> i;
push(i); // Illegal: tries to copy i.
}
If this compiled, it would trivially break the invariant of unique_ptr, that only one unique_ptr owns an object, because both i and the local argument in push would own that int, so it is illegal. unique_ptr is move only, it's not copyable. It has nothing to do with derived to base conversion, which unique_ptr handles completely correctly.
If push owns the object, then use std::move to move it there. If it doesn't, then use a raw pointer or reference, because that's what you use for a non-owning alias.
Well, if your functions operate on the (pointed to) object itself and don't need its address, neither take any ownership, and, as I guess, always need a valid object (fail when passed a nullptr), why do they take pointers at all?
Do it properly and make them take references:
void Push(const Object& object) { ... }
Then the calling code looks exactly the same for raw and smart pointers:
auto number = NewNumber(5);
Push(*number);
EDIT: But of course no matter if using references or pointers, don't make Push take a std::unique_ptr if it doesn't take ownership of the passed object (which would make it steal the ownership from the passed pointer). Or in general don't use owning pointers when the pointed to object is not to be owned, std::shared_ptr isn't anything different in this regard and is as worse a choice as a std::unique_ptr for Push's parameter if there is no ownership to be taken by Push.
If Push does not take owenrship, it should probably take reference instead of pointer. And most probably a const one. So you'll have
Push(*number);
Now that's obviously only valid if Push isn't going to keep the pointer anywhere past it's return. If it does I suspect you should try to rethink the ownership first.
Here's a polymorphism example using unique pointer:
vector<unique_ptr<ICreature>> creatures;
creatures.emplace_back(new Human);
creatures.emplace_back(new Fish);
unique_ptr<vector<string>> pLog(new vector<string>());
for each (auto& creature in creatures)
{
auto state = creature->Move(*pLog);
}

Is it appropriate to return a pointer to static data of a function?

Well, I need to return a pointer to an instance of a class that will be created inside a function. Is this appropriate?
this is example code:
template <typename T>
ImplicatedMembershipFunction<T>*
TriangularMF<T>::minImplicate(const T &constantSet) const
{
static ImplicatedType* resultingSet = new ImplicatedType();
// do something to generate resultingSet...
return resultingSet;
}
I want to return pointers, because need to have subclasses of a base class in a container. In the above code ImplicatedType is a class defined in TriangularMF<T> and derived from ImplicatedMembershipFunction<T>. There will be various template classes like TriangularMF that the have a nested class derived from ImplicatedMembershipFunction<T>, I need to treat with them in same way. For example, outside the library, I may want to do something like :
TriangularMF<double> trmf(0,1,2);
TrapesoidalMF<double> trpmf(0,1,3,2); // a class like TriangularMF but
// ImplicatedType is different
ImplicatedMembershipFunction<double>* itrmf = trmf.implicate(0.6);
ImplicatedMembershipFunction<double>* itrpmf = trpmf.implicate(0.6); // same as above.
// use them in the same way:
vector<ImplicatedMembershipFunction<double>*> vec;
vec.push_back(itrmf);
vec.push_back(itrpmf);
The reason that I don't want to use C++11 features like move semantics or std::shared_ptr is that I don't like to force my teammates to install newer versions of g++ on their computers. I can't give them a compiled version of the library, because it's heavily templated.
EDIT
The library is going to be threaded. Especially, the TriangularMF<T>::minImplicate will run in multiple threads at same time. So, making the minImplicate a mutal task, makes no sense for the performance.
Returning a pointer is not itself the issue, but you have to define a clean "policy" about whoi creates and who destroy.
In your code, you define a static pointer that is initialized with a new object the very first time its (pointer) definition is encountered.
The pointer itself will be destroyed just after main() will return, but what about the object it points to?
If you let something else to take care of the deletion, your function will continue to return that pointer even if the object is no more there. If you let it there, it will be killed out at the end of the program (not a "dangerous" leak, since it is just one object, but what about if its destructor has to take some sensible actions?)
You have most likely to declare, not a static pointer, but a static OBJECT, and return ... its address or its reference.
In that way the object is granted to exist up to program termination and to be properly destroyed after main() returns.
template <typename T>
ImplicatedMembershipFunction<T>*
TriangularMF<T>::minImplicate(const T &constantSet) const
{
static ImplicatedType resultingSet(....);
return &resultingSet;
}
Note that I eliminated your "do something to ..." since it will be executed every time (not just the very first) To initialize ImplicatedType, you had better to rely on the constructor.
Or, if you cannot construct it in one shot, do something like
template <typename T>
ImplicatedMembershipFunction<T>*
TriangularMF<T>::minImplicate(const T &constantSet) const
{
static ImplicatedType* resultingSet=0;
static bool init=true;
if(init)
{
init=false;
static ImplicatedType result;
resultingSet=&result;
// do something to generate resultingSet...
}
return resultingSet;
}
If you are in a multithreading situation, you also need a static mutex an lock it before if(init), unlocking at return.
This is a commonly used idiom for singletons:
class CMyClass {};
CMyClass& MyClass() {
static CMyClass mclass;
return mclass;
}
CMyClass will be constructed on first MyClass() function call.
it looks quite like your code, with the exception for pointer which will cause problems with destroying such crated instance. If you dont want to use shared_ptr here, then consider writing your own shared_ptr like template, then it should work fine.
[edit] if this code is going to be used in multithreaded environment, then using smart pointer here will be tricky
You can use this technique, but return a reference. The caller can take the address of the result if they need a pointer to store.
template <typename T>
ImplicatedMembershipFunction<T> &
TriangularMF<T>::minImplicate(const T &constantSet) const
{
static ImplicatedType* resultingSet = new ImplicatedType();
// do something to generate resultingSet...
return *resultingSet;
}
But, the danger of the code is that it is not inherently MT-safe. But if you know the code inside minImplicate is thread safe, or your code is single threaded, there are no issues.

How do I make an abstract class properly return a concrete instance of another abstract class?

I recently reworked one of my own libraries to try out separating interface from implementation. I am having on final issue with a class that is meant to return an instance of another class.
In the interface definition, I do something like
struct IFoo
{
virtual const IBar& getBar() = 0;
}
and then in the concrete Foo getBar looks like
const IBar& Foo::getBar()
{
Bar ret = Bar();
return ret;
}
The problem is ret gets deleted as soon as getBar is done, causing a big crash when the copy constructor tries to use Bar like so
const Bar myBar = myFoo.getBar();
I have been reading various things, and I know returning by reference is frowned upon, but I do not see any other way (I do not want to return Bar* because I do not want to have to manually delete the return value).
What is the proper way (if any way exists) for an abstract class to return an instance of a concrete class derived from another abstract class?
Note I did see this solution: returning an abstract class from a function
but I do not want to make the return value static and loose thread safety.
Use smart pointers.
These are pointers deleted when not used anymore (see for example http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/smart_ptr.htm).
You can also return the object by value.
Some compilers provide the Return value optimization which optimize away the copy when returning an object.
Edit:
Sorry. I skimmed through the question and somehow missed the fact that inheritance is involved. Assuming that getBar() can return various kind of IBar returning an IBar pointer makes a lot of sense.
By returning a pointer to base the concrete object is kept intact. The slicing problem is avoided and the original vtbl pointer is available to make virtual function calls. Also (as you noted in your comment) returning an instance of an abstract class is just impossible.
Instead of returning a raw pointer I suggest you return a shared_ptr<IBar> to simplify memory management.
const shared_ptr<IBar> Foo::getBar()
{
shared_ptr<IBar> ret(new Bar());
return ret;
}
Then use it this way:
shared_ptr<IBar> pIBar(foo.getBar());
pIBar->myVirtualFunction();
shared_ptr is the most commonly used smart pointer type in C++0x. If you have a sufficiently recent compiler it will be in the std namespace. Older compiler may have it in the tr1 namespace and it's also part of boost.
You're returning a reference to a local variable. As soon as the function returns the reference, the stack gets popped and that Bar object ceases to exist.
EDIT: I didn't read the whole thing. You'll probably need to use a smart pointer.
Actually, is there any reason why you need to return a base class reference? You could avoid any smart pointer messiness by returning an object of the concrete type itself, since C++ allows covariant return types.
Since you want to transfer ownership of the returned object to the caller, the caller will have to destroy the object. In other words, returning IBar * is your best bet. If you are worried about having to manually call delete, you should look into using a smart pointer package, e.g. boost::shared_ptr.
If you don't want to take care of deletion then you have to use SmartPointers.
In C++ this is the only way to have object "deletes itself" when it is appropriated.
http://en.wikipedia.org/wiki/Smart_pointer
The object that has been created on the stack will be destructed when your stack is removed. The stack is removed when the function exits.
Instead, try something like this:
struct Foo : public IFoo
{
Bar m_Bar;
public:
virtual const IBar& getBar()
{
return m_Bar;
}
}