It's common to declared contained objects as a pointers to that class, while "forward declarating" them in header file. This in order to reduce physical dependencies in code.
For example
class B; // forward declaration
class A {
private:
B* pB;
};
Would it be good idea to declare such a member as shared_ptr, instead of naked pointer?
I would prefer scoped_ptr, but AFAIK it it won't be in standard.
Yes you can (should ?).
This is a common practice. As you stated it avoids the need to explicitely call delete().
You can go even further. Here is an example:
class RSAKey
{
public:
RSAKey();
private:
shared_ptr<RSA> d_rsa; // A pointer to a RSA structure from OpenSSL
}
Which I initialize like this:
RSAKey::RSAKey()
{
RSA* rsa = RSA_generate_key(1024, 1, NULL, NULL);
if (NULL == rsa) throw DummyException();
d_rsa.reset(rsa, RSA_free); // Note the specific release method.
}
When d_rsa will no longer be used, an automatic call to RSA_free() will occur. Isn't that cool ?!
Update
If C++11 is an option, you should probably better use std::unique_ptr instead which has less overhead and is movable.
It depends on how you want your enclosing class to behave in regards to copy.
If this pointer is not passed out of your class impelementation and execution speed is crucial, use scoped_ptr instead of shared_ptr. shared_ptr has an overhead.
Using a shared_ptr would allow you to pass ownership to another object, so that it doesn't get destroyed when your outer object is destroyed. You state that this won't be a concern in this particular case.
The only advantage a smart pointer will have is that you won't need to remember to put a delete pB in your destructor. That may be enough advantage for most people.
When you don't need to worry about ownership issues, even an auto_ptr will be good enough.
In the case of a composition, yes it is a good idea if you don't want physical dependency. Then your B will be destroyed automatically when A is.
If you don't mind physical dependency, you can just hold the data member by value.
(You can also check for the pimpl idiom if physical dependency is a problem.)
Related
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
I wish to create a class (class1) which contains another class (class2) as a data member. I then want class2 to know about class1 and be able to communicate with it.
I could have a reference to class1 as a member in class2 but that then means I need to provide a reference to class1 as a parameter in the constructor of class2 and use initialiser lists which I don't want. I'm trying to do this without needing the constructor to do it.
I would like for class2 to have a member function called Initialise which could take in the reference to class1, but this seems impossible without using pointers. What would people recommend here? Thanks in advance.
The code is completely simplified just to get the main idea across :
class class1
{
public:
InitialiseClass2()
{
c2.Initialise(this);
}
private:
class2 c2;
};
class class2
{
public:
Initialise(class1* c1)
{
this->c1 = c1;
}
private:
class1* c1;
};
this seems impossible without using pointers
That is incorrect. Indeed, to handle a reference to some other object, take a reference into a constructor:
class class2
{
public:
class2(class1& c1)
: c1(c1)
{}
private:
class1& c1;
};
The key here is to initialise, not assign, the reference. Whether this is possible depends on whether you can get rid of your Initialise function and settle into RAII (please do!). After that, whether this is actually a good idea depends on your use case; nowadays, you can almost certainly make ownership and lifetime semantics much clearer by using one of the smart-pointer types instead — even if it's just a std::weak_ptr.
Anyway, speaking more generally.
Are pointers "always" bad? No, of course not. I'd almost be tempted to say that managing dynamic memory yourself is "always" bad, but I won't make a generalisation.
Should you avoid them? Yes.
The difference is that the latter is a guideline to steer you away from manual memory management, and the former is an attempted prohibition.
No, using pointers in C++ is not bad at all, and I see this anti-advice over and over again. What is bad is managing pointers by yourself, unless you are creating a pointer-managing low-level entity.
Again, I shall make a very clear distinction. Using pointers is good. Very few real C++ programs can do without USING pointers. Managing pointers is bad, unless you are working on pointer manager.
A pointer can be nullptr whereas a reference must always be bound to something (and cannot be subsequently re-bound to something else).
That's the chief distinction and the primary consideration for your design choice.
Memory management of pointers can be delegated to std::shared_ptr and std::unique_ptr as appropriate.
well, I never had the need to 2 classes to have reciprocal reference and for good reasons, how do you know how to test those classes? If later you need to change something in the way the 2 classes communicates you will probably have to change code in both classes). You can workaround in many ways:
You may need in reality just 1 class ( you have broken into much classes)
You can register a Observer for a class (using a 3rd class, in that case you will end up with a pointer, but at least the 2 classes are less coupled and it is easier test them).
You can think (maybe) to a new interface that require only 1 class to call methods on the other class
You could pass a lambda (or a functor if you do not have C++11) into one of the methods of the class removing the need to a back reference
You could pass a reference of the class inside a method.
Maybe you have to few classes and in reality you need a third class than communicates with both classes.
It is possible you need a Visitor (maybe you really need multiple dispatch)
Some of the workarounds above need pointers, some not. To you the choice ;)
NOTE: However what you are doing is perfectly fine to me (I see you do some trickery only in constructors, but probably you have more omitted code, in wich case that can cause troubles to you). In my case I "register" one class into another, then after the constructor called I have only one class calling the other and not viceversa.
First of all whenever you have a circular dependency in your design think about it twice and make sure it's the way to go. Try to use the Dependency inversion principle in order to analyze and fix your dependencies.
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
Pointers are a powerful programming tool. Like any other feature in the C++ (or in any programming language in general) they have to be used when they are the right tool. In C++ additionally you have access to references which are similar to pointers in usage but with a better syntax. Additionally they can't be null. Thus they always reference a valid object.
So use pointers when you ever need to but try to avoid using raw pointers and prefer a smart pointer as alternative whenever possible. This will protect you against some trivial memory leak problems but you still have to pay attention to your object life-cycle and for each dynamically allocated object you should know clearly who create it and when/whom will release the memory allocated for the object.
Pointers (and references) are very useful in general because they could be used to pass parameters to a method by reference so you avoid passing heavy objects by value in the stack. Imagine the case for example that you have a very big array of heavy objects (which copy/= operator is time consuming) and you would like to sort these objects. One simple method is to use pointers to these objects so instead of moving the whole object during the sorting operation you just move the pointers which are very lightweight data type (size of machine address basically).
When initializing a shared_ptr member variable:
// .h
class Customer
{
public:
Customer();
private:
std::shared_ptr<OtherClass> something_;
}
// .cpp
Customer():
something_(new OtherClass())
{
}
vs.
Customer():
something_(std::make_shared<OtherClass>())
{
}
Is the make_shared version allowed? I always seem to see the first version, which is preferred?
The only times when make_shared is not allowed are:
If you're getting a naked pointer allocated by someone else and storing it in shared_ptr. This is often the case when interfacing with C APIs.
If the constructor you want to call is not public (make_shared can only call public constructors). This can happen with factory functions, where you want to force users to create the object from the factory.
However, there are ways to get around this. Instead of having a private constructor, have a public constructor. But make the constructor take a type with can only be constructed by those with private access to the class. That way, the only people who can call make_shared with that object type are those with private access to the class.
So yes, you can do this.
In this case, using make_shared is not just allowed, but it is better to use it. If you use new, it will allocate memory for your Customer somewhere and then memory for your shared_ptr somewhere else, storing both strong and weak references (for weak pointers and shared pointers). If you use the make_shared you would have only one place in memory with everything and therefore only one new.
I'm not sure that I was really clear, this was the purpose of the GotW #89, read it, it is well explained there.
In this question I asked "pimpl: shared_ptr or unique_ptr" I've been convinced that the proper usage of the pimpl idiom is to use a unique_ptr, not a shared_ptr. It should act to the user as if there is no pointer at all, whereas quite clearly the shared_ptr introduces aliasing upon copying, which definitely acts like a pointer.
So, lets say a user wants to create a shared_ptr to my pimpl object (say if they want actually want multiple aliases to it). For example:
shared_ptr<my_pimpl> p(new my_pimpl());
That would result in a shared_ptr pointing to a unique_ptr pointing to my implementation.
It would be nice if I could achieve something like the following:
my_pimpl x; // (1)
shared_ptr<my_pimpl> p(new my_pimpl()); // (2) Pointer to pointer here.
x.f(); // (3)
p->f(); // (4)
but with somehow getting rid of the pointer to pointer, whilst still maintaining the implementation hiding of pimpl.
Any ideas how to achieve this (I'm happy to change the line (2) and obviously my_pimpl, but want lines (3) and (4) to stay the same).
There are a number of possible approaches depending on your constraints.
1. Create your own shared_my_pimpl class
Create a class shared_my_pimpl which has the same interface as my_pimpl but internally uses a shared_ptr instead of a unique_ptr. Now create a class shared_ptr_my_pimpl which holds a shared_my_pimpl and has an operator-> which returns a pointer to the shared_my_pimpl, so that you get -> notation instead of . notation for member access. You can add a function make_shared_ptr_my_pimpl to make it look more like shared_ptr usage.
Disadvantages:
The type of the object is not shared_ptr<x> but shared_ptr_my_pimpl; it's just pretending to be a shared_ptr.
You can't get a my_pimpl* or my_pimpl& to the object; it's a different type which just behaves the same.
2. Derive from an interface
Create an interface my_pimpl_interface with all relevant functions pure virtual. Derive both my_pimpl and my_pimpl::impl (your pimpl implementation class) from this interface. Add a function make_shared_my_pimpl which returns a shared_ptr<my_pimpl_interface> to a my_pimpl::impl. You can now refer to both the plain object and the shared_ptr object as my_pimpl_interface&.
Disadvantages:
By making all functions virtual you incur an extra indirection in calling them, which may have been what you were trying to avoid. Your standard my_pimpl object will also pay this overhead.
You should use an interface for this purpose, because then the user of your class can choose whether they want to use shared_ptr or unique_ptr.
Let's say I have a class that allocates some arbitrary member data. There are two common ways that I have seen used (I know that there are others):
class A
{
public:
A();
~A();
//Accessors...
private:
B *mB;
}
A::A()
{
mB = new B();
}
A::~A()
{
delete B;
}
Versus...
class A
{
public:
//Accessors...
private:
B mB;
}
Assume that A itself will be allocated on the heap by consumer code.
In the general case, which method is preferred? I realize that specific situations really encourage one way or the other, but in absence of those demands, is one way preferred? What are the tradeoffs?
The second is the preferred route. Do not use new / delete unless you specifically need a variable to be on the heap or have a lifetime longer than it's container. C++ value types are easier to manage and have less error cases to worry about IMHO
It depends.
In general, If a B is large and unwieldy then it's easier to pass around a pointer to the B than the B itself. So if the B will often be disassociated from the A (f'rinstance if your A's swap B's) then the first way is better.
Using a pointer can also reduce dependencies. If you do it right, A.hh can get by without specifiying what a B is or does (i.e. A.h need not #include "B.hh") so that things that depend on A.hh won't necessarily depend on B.hh.
The price of using pointers is an extra layer of machinery and the dangers of things like lost objects, double-deletion and the dereferencing of uninitialized pointers, so it shouldn't be used unless it actually gives a benefit in your situation. Some people fall in love with pointer techniques and use them everywhere; if they want to improve as programmers they have to grow out of it.
In general, prefer direct composition (the second choice). In that case there is no chance of leaking memory and the object is fully located in a contiguous memory block, allowing better cache locality.
You might use the first option if you're implementing a PIMPL, or you have a need to use one of several possible class types (via inheritance). In that case definitely use a smart pointer (boost::shared_ptr for example) to manage the memory for you.
It depends, mainly, on what you are looking for.
For simplicity's sake: don't use a pointer. Therefore the second choice.
It's easier to manage (no need to worry about memory management, deep copying, deep constness, etc...).
However you might need dynamically allocated attributes sometimes:
if you need polymorphism (otherwise you have a truncation)
if you want to cut down your dependencies (in the header file) --> see PIMPL here
Even in this case though, hand over the responsibility to a smart manager (smart pointer, dedicated pimpl class, etc...)
At work we have a base class, let's call it IntrusiveBase, that acts something like a mixin to allow a class to be stored in a boost:intrusive_ptr. That is, it provides its subclasses with a ref count and defines intrusive_ptr_add_ref and intrusive_ptr_release overloads. The problem is that it is too easy for someone to forget that a particular subclass inherits from IntrusiveBase, and they then store it in some other smart pointer like a scoped_ptr or shared_ptr. That doesn't work because, for example, the scoped_ptr will delete the object when it goes out of scope no matter what the ref count happens to be. We have an assertion in ~IntrusiveBase that the ref count is one, but this is not foolproof because oftentimes there will end up only being the original instance by the time the scoped_ptr goes out of scope. This leaves an insidious failure waiting to happen those few times that the ref count is not one.
Is there any way that I can cause a compile-time failure if someone accidentally does this? Even if I have to do something repetitively for each of the major smart pointer classes, it would be worth it.
Even if I have to do something repetitively for each of the major smart pointer classes, it would be worth it.
In that case, you can specialize them on your InstrusiveBase inheriting types.
namespace boost
{
template<>
class scoped_ptr<InstrusiveBaseSubclass> { }; // scoped_ptr<InstrusiveBaseSubClass> p(new InstrusiveBaseSubClass) won't compile, neither will p->, p.get() etc.
}
This is annoying but it's macro-able, e..g:
class A : InstrusiveBase
{
...
}
NO_SCOPED_PTR(A)
NO_SHARED_PTR(A)
Another option would be to overload new and delete for those classes and make delete private or protected. instrusive_ptr_release could then be made a friend function or similar technique used to actually invoke delete when the ref count dropped to zero.