I have a class that references a bunch of other classes. I want to be able to add these references incrementally (i.e. not all at the same time on the constructor), and I want to disallow the ability to delete the object underlying these references from my class, also I want to test for NULL-ness on these references so I know a particular reference has not been added. What is a good design to accomplish these requirements?
I agree with other comments that you should use boost::shared_ptr.
However if you don't want the class holding these references to part-control the lifetime of the objects it references you should consider using boost::weak_ptr to hold the references then turn this into a shared_ptr when you want to us it. This will allow the referenced objects to be deleted before your class, and you will always know if object has been deleted before using it.
It sounds like you might be trying to build a Service Locator.
As a side-comment: I would personally recommend not doing that, because it is going to make testing really, really painful if you ever want to do it. Constructor injection (Something that you are trying to avoid) will make testing much easier.
Shouldn't you use the refcounted class, so that your reference will be managed until your primary class get destroyed.
You are most likely looking for boost::shared_ptr.
Despite all the recommendations that you use boost:;shared_pointer, it is far from obvious from your post that it would be appropriate to do so, as the class appears to have no ownership semantics. An ordinary C++ pointer will do just fine here.
It is difficult at the end of the day to prevent deletion via smart pointer, as the
smart pointer must, in some form or other, provide access to the underlying dumb pointer, which of course can always be deleted. For some problems there is no technological solution, and in this case a code review is the best way to detect semantic errors in using the contained pointers.
The object you want to reference could be derived from with something like this. That would prevent you from deleting them.
class T
class NonDeletable : public T
{
private:
void operator delete(void*);
};
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).
I'm having trouble getting things organized properly with smart pointers. Almost to the point that I feel compelled to go back to using normal pointers.
I would like to make it easy to use smart pointers throughout the program without having to type shared_ptr<...> every time. One solution I think of right away is to make a template class and add a typedef sptr to it so I can do class Derived : public Object < Derived > .. and then use Derived::sptr = ... But this obviously is horrible because it does not work with another class that is then derived from Derived object.
And even doing typedef shared_ptr<..> MyObjectPtr is horrible because then it needs to be done for each kind of smart pointer for consistency's sake, or at least for unique_ptr and shared_ptr.
So what's the standard way people use smart pointers? Because frankly I'm starting to see it as being too much hassle to use them. :/
So what's the standard way people use smart pointers?
Rarely. The fact that you find it a hassle to use them is a sign that you over-use pointers. Try to refactor your code to make pointers the exception, not the rule. shared_ptr in particular has its niche, but it’s a small one: namely, when you genuinely have to share ownership of a resource between several objects. This is a rare situation.
Because frankly I'm starting to see it as being too much hassle to use them. :/
Agreed. That’s the main reason not to use pointers.
There are more ways to avoid pointers. In particular, shared_ptr really only needs to spelled out when you actually need to pass ownership. In functions which don’t deal with ownership, you wouldn’t pass a shared_ptr, or a raw pointer; you would pass a reference, and dereference the pointer upon calling the function.
And inside functions you almost never need to spell out the type; for instance, you can (and should) simply say auto x = …; instead of shared_ptr<Class> x = …; to initialise variables.
In summary, you should only need to spell out shared_ptr in very few places in your code.
I have a lot of code that creates objects dynamically. So using pointers is necessary because the number of objects is not known from the start. An object is created in one subsystem, then stored in another, then passed for further processing to the subsystem that created it. So that I guess means using shared_ptr. Good design? I don't know, but it seems most logical to ask subsystem to create a concrete object that it owns, return a pointer to an interface for that object and then pass it for further processing to another piece of code that will interact with the object through it's abstract interface.
I could return unique_ptr from factory method. But then I would run into trouble if I need to pass the object for processing multiple times. Because I would still need to know about the object after I pass it to another method and unique_ptr would mean that I lose track of the object after doing move(). Since I need to have at least two references to the object this means using shared_ptr.
I heard somewhere that most commonly used smart pointer is unique_ptr. Certainly not so in my application. I end up with using shared_ptr mush more often. Is this a sign of bad design then?
I came accross several questions where answers state that using T* is never the best idea.
While I already make much use of RIIC, there is one particular point in my code, where I use T*. Reading about several auto-pointers, I couldn't find one where I'd say that I have a clear advantage from using it.
My scenario:
class MyClass
{
...
// This map is huge and only used by MyClass and
// and several objects that are only used by MyClass as well.
HashMap<string, Id> _hugeIdMap;
...
void doSomething()
{
MyMapper mapper;
// Here is what I pass. The reason I can't pass a const-ref is
// that the mapper may possibly assign new IDs for keys not yet in the map.
mapper.setIdMap(&_hugeIdMap);
mapper.map(...);
}
}
MyMapper now has a HashMap<...>* member, which - according to highly voted answers in questions on unrelated problems - never is a good idea (Altough the mapper will go out of scope before the instance of MyClass does and hence I do not consider it too much of a problem. There's no new in the mapper and no delete will be needed).
So what is the best alternative in this particular use-case?
Personally I think a raw pointer (or reference) is okay here. Smart pointers are concerned with managing the lifetime of the object pointed to, and in this case MyMapper isn't managing the lifetime of that object, MyClass is. You also shouldn't have a smart pointer pointing to an object that was not dynamically allocated (which the hash map isn't in this case).
Personally, I'd use something like the following:
class MyMapper
{
public:
MyMapper(HashMap<string, Id> &map)
: _map(map)
{
}
private:
HashMap<string, Id> &_map
};
Note that this will prevent MyMapper from having an assignment operator, and it can only work if it's acceptable to pass the HashMap in the constructor; if that is a problem, I'd make the member a pointer (though I'd still pass the argument as a reference, and do _map(&map) in the initializer list).
If it's possible for MyMapper or any other class using the hash map to outlive MyClass, then you'd have to start thinking about smart pointers. In that case, I would probably recommend std::shared_ptr, but you'd have to use it everywhere: _hugeIdMap would have to be a shared_ptr to a dynamically allocated value, not a regular non-pointer field.
Update:
Since you said that using a reference is not acceptable due to the project's coding standards, I would suggest just sticking with a raw pointer for the reasons mentioned above.
Naked pointers (normally referred to as raw pointers) are just fine when the object has no responsibility to delete the object. In the case of MyMapper then the pointer points to an object already owned by MyClass and is therefore absolutely fine to not delete it. The problem arises when you use raw pointers when you do intend for objects to be deleted through them, which is where problems lie. People only ask questions when they have problems, which is why you almost always see it only used in a problematic context, but raw pointers in a non-owning context is fine.
How about passing it into the constructor and keeping a reference (or const-reference) to it? That way your intent of not owning the object is made clear.
Passing auto-pointers or shared-pointers are mostly for communicating ownership.
shared pointers indicate it's shared
auto-pointers indicate it's the receivers responsibility
references indicate it's the senders responsibility
blank pointers indicate nothing.
About your coding style:
our coding standards have a convention that says never pass non-const references.
Whether you use the C++ reference mechanism or the C++ pointer mechanism, you're passing a (English-meaning) reference to the internal storage that will change. I think your coding standard is trying to tell you not to do that at all, not so much that you can't use references to do so but that you can do it in another way.
In my new project I wish to (mostly for to see how it will work out) completely ban raw pointers from my code.
My first approach was to let all classes inherit from this simple class:
template
class Base
{
public:
typedef std::shared_ptr ptr;
};
And simple use class::ptr wherever I need a pointer.
This approach seemed suitable until I realized sometimes my objects wish to pass the 'this' pointer to other objects. Letting my objects just wrap it inside a shared_ptr won't do since then there could be two owners for the same pointer. I assume this is bad.
My next idea was to change the 'Base' class to implement reference counting itself, thus every instance of classes that inherits from 'Base' can only have one count.
Is this a good solution, are there any better and can boost and/or stl already solve this problem for me?
You may want to take a look at enable_shared_from_this.
On another note, when using shared_ptr, you need to be aware of the possibility of circular references. To avoid this, you can use weak_ptr. This means you will need some way to distinguish between the two of them, so simply having a typedef class::ptr may not suffice.
This is also a question that I asked in a comment in one of Miško Hevery's google talks that was dealing with dependency injection but it got buried in the comments.
I wonder how can the factory / builder step of wiring the dependencies together can work in C++.
I.e. we have a class A that depends on B. The builder will allocate B in the heap, pass a pointer to B in A's constructor while also allocating in the heap and return a pointer to A.
Who cleans up afterwards? Is it good to let the builder clean up after it's done? It seems to be the correct method since in the talk it says that the builder should setup objects that are expected to have the same lifetime or at least the dependencies have longer lifetime (I also have a question on that). What I mean in code:
class builder {
public:
builder() :
m_ClassA(NULL),m_ClassB(NULL) {
}
~builder() {
if (m_ClassB) {
delete m_ClassB;
}
if (m_ClassA) {
delete m_ClassA;
}
}
ClassA *build() {
m_ClassB = new class B;
m_ClassA = new class A(m_ClassB);
return m_ClassA;
}
};
Now if there is a dependency that is expected to last longer than the lifetime of the object we are injecting it into (say ClassC is that dependency) I understand that we should change the build method to something like:
ClassA *builder::build(ClassC *classC) {
m_ClassB = new class B;
m_ClassA = new class A(m_ClassB, classC);
return m_ClassA;
}
What is your preferred approach?
This talk is about Java and dependency injection.
In C++ we try NOT to pass RAW pointers around. This is because a RAW pointer have no ownership semantics associated with it. If you have no ownership then we don't know who is responsible for cleaning up the object.
I find that most of the time dependency injection is done via references in C++.
In the rare cases where you must use pointers, wrap them in std::unique_ptr<> or std::shared_ptr<> depending on how you want to manage ownership.
In case you cannot use C++11 features, use std::auto_ptr<> or boost::shared_ptr<>.
I would also point out that C++ and Java styles of programming are now so divergent that applying the style of one language to the other will inevitably lead to disaster.
This is interesting, DI in C++ using templates:
http://adam.younglogic.com/?p=146
I think the author is making the right moves as to not translate Java DI into C++ too literally. Worth the read.
I've recently been bitten by the DI bug. I think it solves a lot of complexity problems, especially the automated part. I've written a prototype which lets you use DI in a pretty C++ way, or at least I think so. You can take a look at the code example here: http://codepad.org/GpOujZ79
The things that are obviously missing: no scoping, no binding of interface to implementation. The latter is pretty easy to solve, the former, I've no idea.
I'd be grateful if anyone here has an opinion on the code.
Use RAII.
Handing a raw pointer to someone is the same as handing them ownership. If that's not what you want to do, you should give them some kind of facade that also knows how to clean up the object in question.
shared_ptr<> can do this; the second argument of its constructor can be a function object that knows how to delete the object.
In C++, normally, when you done things right, you don't need to write destructors at all in most cases. You should use smart pointers to delete things automatically. I think, builder don't looks like the owner of the ClassA and ClassB instances. If you don't like to use smart pointers, you should think about objects life time and their owners.
Things get complicated if you don't settle on the question of ownership once and for all. You will simply have to decide in your implementation if it's possible that dependencies live longer than the objects they are injected into.
Personally I'd say no: the object into which the dependency is injected will clean up afterwards. Trying to do it through the builder means that the builder will have to live longer than both the dependency and the object into which it is injected. This causes more problems than it solves, in my opinion, because the builder does not serve any more useful purpose after the construction with the dependency injection has been completed.
Based on my own experience, it is best to have clear ownership rules. For small concrete objects, it is best to use direct copy to avoid cross dependency.
Sometimes cross dependency is unavoidable, and there is no clear ownership. For example, (m) A instances own (n) B instances, and certain B instances can be owned by multiple As. In this case, the best approach is to apply reference counting to B, in the way similar to COM reference counting. Any functions that take possession of B* must increase reference count first, and decrease it when releasing the possession.
I also avoid using boost::shared_ptr as it creates a new type (shared_ptr and B* become two distinct types). I found that it brings more headaches when I add methods.
You can also check the FFEAD Dependency Injection. It provides DI on the lines of Spring for JAVA and has a non-obtrusive way of dealing with things. It also has a lot of other important features like in-built AJAX Support,Reflection,Serialization,C++ Interpreter,Business Components For C++,ORM,Messaging,Web-Services,Thread-Pools and an Application Server that supports all these features.