I'm designing a software tool in which there's an in-memory model, and the API user can get objects of the model, query them and set values.
Since all the model's objects belong to a single model, and most operations must be recorded and tested, etc., each created object must be registered to the Model object. The Model stores all objects as std::unique_ptr since it's the only owner of them. When needed, it passes raw pointers to users.
What makes me worry is the possibility that the user calls delete on these pointers. But if I use std::shared_ptr, the user can still use get() and call delete on that. So it's not much safer.
Another option I though of is to refer to objects by a name string, or pass ObjectReference objects instead of the real objects, and then these ObjectReferences can be destroyed without affecting the actual stored object.
These References work somewhat like a client: You tell them what to do, and they forward the request to the actual object. It's a lot of extra work for the developer, but it protectes the pointers.
Should I be worried about the pointers? Until now I was using smart pointers all the time, but now I need to somehow allow the user to access objects managed by a central model, without allowing the user to delete them.
[Hmmm... maybe make the destructor private, and let only the unique_ptr have access to it through a Deleter?]
You shouldn't bother about users calling delete on your objects. It's one of those things that are perfectly fine as a documented constraint, any programmer violating that only deserves whatever problem he runs into.
If you still really want to explicitly forbid this, you could either write a lightweight facade object that your users will pass by value (but it can be lot of work depending on the number of classes you have to wrap) or, as you said, make their destructor private and have unique_ptr use a friend deleter.
I for one am not fond of working through identifiers only, this can quickly lead to performance issues because of the lookup times (even if you're using a map underneath).
Edit: Now that I think of it, there is a way in between identifiers and raw pointers/references: opaque references.
From the point of view of the users, it acts like an identifier, all they can do is copy/move/assign it or pass it to your model.
Internally, it's just a class with a private pointer to your objects. Your model being a friend of this class, it can create new instances of the opaque reference from a raw pointer (which a user can't do), and use the raw pointer to access the object without any performance loss.
Something along the lines of:
class OpaqueRef
{
// default copy/move/assignment/destructor
private:
friend class Model;
Object* m_obj;
OpaqueRef(Object& obj) : m_obj(&obj) {}
};
Still, not sure if it's worth the trouble (I stand by my first paragraph), but at least you got one more option.
Personally, I'd keep the internal pointer in the model without exposing it and provide an interface via model ids, so all operations go through the interface.
So, you could create a separate interface class that allows modification of model attributes via id. External objects would only request and store the id of the object they want to change.
Related
I have a basic design that consists of three classes : A Data class, A Holder class wich holds and manages multiple Data objects, and a Wrapper returned by the Holder wich contains a reference to a Data object.
The problem is that Wrapper must not outlive Holder, or it will contain a dangling reference, as Holder is responsible for deleting the Data objects. But as Wrapper is intended to have a very short lifetime (get it in a function, make some computation on its data, and let it go out of scope), this should not be a problem, but i'm not sure this is a good design.
Here are some solutions i thought about:
-Rely on the user reading the documentation, technically the same thing happens with STL iterators
-Using shared_ptr to make sure the data lasts long enought, but it feels like overkill
-Make Wrapper verify its Holder still exists each time you use it
-Any idea?
(I hope everyone can understand this, as english is not my native language)
Edit : If you want to have a less theoric approach, this all comes from a little algorithm i'm trying to write to solve Sudokus, the Holder is the grid, the Data is the content of each box (either a result or a temporary supposition), and the Wrapper is a Box class wich contains a reference to the Data, plus additional information like row and column.
I did not originally said it because i want to know what to do in a more general situation.
Only ever returning a Wrapper by value will help ensure the caller doesn't hold onto it beyond the calling scope. In conjunction with a comment or documentation that "Wrappers are only valid for the lifetime of the Holder that created them" should be enough.
Either that or you decide that ownership of a Data is transferred to the Wrapper when the Wrapper is created, and the Data is destroyed along with the Wrapper - but what if you want a to destroy a Wrapper without deleting the Data? You'd need a method to optionally relinquish ownership of the Data back to the Holder.
Whichever you choose, you need to decide what owns (ie: is responsible for the lifetime of) Data and when - once you've done that you can, if you want, use smart pointers to help with that management - but they won't make the design decision for you, and you can't simply say "oh I'll use smart pointers instead of thinking about it".
Remember, if you can't manage heap memory without smart pointers - you've got no business managing heap memory with them either!
To elaborate on what you have already listed as options,
As you suggested, shared_ptr<Data> is a good option. Unless performance is an issue, you should use it.
Never hold a pointer to Data in Wrapper. Store a handle that can be used to get a pointer to the appropriate Data object. Before Data is accessed through Wrapper, get a pointer the Data object. If the pointer is not valid, throw an exception. If the pointer is valid, proceed along the happy path.
From here: http://www.oodesign.com/proxy-pattern.html
Applicability & Examples
The Proxy design pattern is applicable when there is a need to control
access to an Object, as well as when there is a need for a
sophisticated reference to an Object. Common Situations where the
proxy pattern is applicable are:
Virtual Proxies: delaying the creation and initialization of expensive
objects until needed, where the objects are created on demand (For
example creating the RealSubject object only when the doSomething
method is invoked).
Protection Proxies: where a proxy controls access to RealSubject
methods, by giving access to some objects while denying access to
others.
Smart References: providing a sophisticated access to certain objects
such as tracking the number of references to an object and denying
access if a certain number is reached, as well as loading an object
from database into memory on demand.
Well, can't Virtual Proxies be created by creating an individual function (other than the constructor) for a new object?
Can't Protection Proxies be created by simply making the function private, and letting only the derived classes get the accesses? OR through the friend class?
Can't Smart References be created by a static member variable which counts the number of objects created?
In which cases should the Proxy method be preferred on the access specifiers and inheritance?
What's the point that I am missing?
Your questions are a little bit abstract, and i'm not sure i can answer at all well, but here are my thoughts on each of them. Personally i dont agree that some of these things are the best designs for the job, but that isn't your question, and is a matter of opinion.
Virtual Proxies
I don't understand what you are trying to say here at all. The point of the pattern here is that you might have an object A that you know will take 100MB, and you don't know for sure that you will ever need to use this object.
To avoid allocating memory for this object until it is needed you create a dummy object B that implements the same interface as A, and if any of its methods are called B creates an instance of A, thus avoiding allocating memory until it is needed.
Protection Proxies
Here i think you have misunderstood the use of the pattern. The idea is to be able to dynamically control access to an object. For example you might want class A to be able to access class B's methods unless condition C is true. As i'm sure you can see this could not be achieved through the use of access specifiers.
Smart Referances
Here i think you misunderstand the need for smart pointers. As this is quite a complicated topic i will simply provide a link to a question about them: RAII and smart pointers in C++
If you have never programmed in a language like C where you manage your memory yourself then this might explain the confusion.
I hope this helps to answer some of your questions.
EDIT:
I didn't notice that this was tagged c++ so i assume you do in fact recognize the need to clean up dynamic memory. The single static reference count will only work if you only intend to ever have one instance of your object. If you create 2000 instances of an object, and then deleted 1999 of them none of them would have their memory freed until the last one left scope which is clearly not desirable (That is assuming you had kept track of the locations of all the allocated memory in order to be able to free it!).
EDIT 2:
Say you have a class as follows:
class A {
public:
static int refcount;
int* allocated_memory;
A() {
++refcount;
allocated_memory = new int[100000000];
}
~A() {
if(! --refcount) {
delete [] allocated_memory;
}
}
}
And some code that uses it:
int main() {
A problem_child; // After this line refcount == 1
while(true) {
A in_scope; // Here refcount == 2
} // We leave scope and refcount == 1.
// NOTE: in_scope.allocated_memory is not deleted
// and we now have no pointer to it. Leak!
return;
}
As you can see in the code refcount counts all references to all objects, and this results in a memory leak. I can explain further if you need, but this is really a seperate question in its own right.
I am no expert, but here are my thoughts on Virtual Proxies : If we control the initialization via a separate function say bool Create(); then the responsibility and control of Initialization lies with the client of the class. With virtual proxies , the goal is to retain creation control within the class, without client being aware of that.
Protection Proxies: The Subject being protected might have different kinds of clients, ones which need to get unprotected/unrestricted access to all Subject methods and the others which should be allowed access to a subset of methods hence need for Protection proxy.
A proxy is an object behaving as a different object to add some control/behavior. A smart pointer is a good example: it accesses the object as if you would use a raw pointer, but it also controls the lifetime of that object.
It's good to question whether there are alternatives to standard solutions to problems. Design Patterns represent solutions that have worked for many folks and have the advantage that there's a good chance that an experienced programmer coming to the code will recognize the pattern and so find maintaining the code easier. However, all designs represent trade-offs and patterns have costs. So you are right to challenge the use of patterns and consider alternatives.
In many cases design is not just about making code work, but considering how it is structured. Which piece of code "knows" what. You proposal for an alternative for Virtual Prozy moves (as fizzbuzz says) knowledge of creation from the proxy to the client - the client has to "know" to call Create() and so is aware of the life-cycle of the class. Whereas with the proxy he just makes an object that he treats as the worker, then invisibly creation happens when the proxy decides it makes sense. This refactoring of responsibility into the proxy is found to valuable, it allows us in the future to change those life-cycle rules without changing any clients.
Protection proxy: your proposal requires that clients have an inheritance relationship so that they can use protected methods. Generally speaking that couples client and worker too tightly, so we introduce a proxy.
Smart reference: no, a single static count is no good. You need to count references to individual instances.
If you carefully work through each case you will find there are merits to the design patterns. If you try to implement an alternative you start with some code that sems simpler that the design pattern and then discover that as you start to refactor and improve the code, removing deuplicationand so on you end up reinventing the design pattern - and that's a really nice outcome.
I am developing a Darwinian evolution simulation. For performance reasons, it's written in C++. The sim is represented by an instance of World. The animals are represented by instances of Animal, a fairly complicated object. World has two important methods:
animal_at(int i)
and
evolve(int n).
animal_at returns a non-null raw pointer to the instance of Animal that represents the i-th animal.
evolve advances the simulation possibly invalidating any pointer returned by animal_at.
I want to make the sim and the animals easily accessible from outside. I have python-specific bindings, but i'm considering learning CORBA or Ice to implement a more generic interface. The problem is how I should expose the animals. I have two ideas, none of which feels satisfactory:
1) Rewrite the code slightly to use shared_ptr instead of a raw ptr and use a middleware that understands shared_ptr semantics.
2) Generate a "deep lazy proxy" that has the same structure as Animal. Its members would be proxies to members of Animal, recursively. animal_at would be actually called in the last moment before referring to the actual data -- the pointer would be used and immediately tossed away. This would implement the "last moment" semantics.
I dislike 1) because I would have to introduce a "zombie" state of the object, which looks inelegant to me.
I dislike 2) because the sole purpose of the proxy is to implement the "last moment" semantics.
I am looking for an automatic non-intrusive way (using code-generation) to achieve this, because I don't want to obscure the meaning of the original code. Is there any "official" name for what I call "last moment" semantics?
There is an option of using boost::weak_ptr. You can pass these around, they have to use lock() to get the underlying shared_ptr so they can see if the object no longer exists.
The lifetime of the object is determined only by the places where a shared_ptr is held. There must therefore be at least one of these at all times during the lifetime of the object, and you need one before you can create a weak_ptr.
Firstly, you might consider xml-rpc instead of CORBA as middleware (more standard use nowadays).
Secondly, external users work with marshalled data. They send a marshalled reference over the middleware and expect marshalled information based on their request and reference, so I don't see how this works together with "last moment" sementics and pointers. You either keep all your temporary animals, so external users can query them or you probably have to send a lot exceptions for not found animals. (or you let them request the "latest" animal)
If your animal_at function returns a pointer that can be invalidated at any point in the future, you might try having it return a smart pointer (I'd suggest a shared_ptr over a weak_ptr here, but you can get away with the weak pointer if you are careful with the implementation). However, instead of pointing directly to an Animal object, have it point to a boost::optional<Animal> object. That way, when you invalidate the pointer, you can set the invalid flag on the pointer and any user of the newly invalidated object have the ability to check to see if they need to get a new pointer.
I don't get why you want to export a pointer instead of exporting an interface which seems exactly the "last moment" semantics that you want. Your animal_at could return an object id, not a pointer, and the interface would give all the required access to the object, like dosomething(id, params). The interface could also include lock/unlock stuff to enable atomic access.
I have to write a bunch of DTOs (Data Transfer Objects) - their sole purpose is to transfer data between client app(s) and the server app, so they have a bunch of properties, a serialize function and a deserialize function.
When I've seen DTOs they often have getters and setters, but is their any point for these types of class? I did wonder if I'd ever put validation or do calculations in the methods, but I'm thinking probably not as that seems to go beyond the scope of their purpose.
At the server end, the business layer deals with logic, and in the client the DTOs will just be used in view models (and to send data to the server).
Assuming I'm going about all of this correctly, what do people think?
Thanks!
EDIT: AND if so, would their be any issue with putting the get / set implementation in the class definition? Saves repeating everything in the cpp file...
If you have a class whose explicit purpose is just to store it's member variables in one place, you may as well just make them all public.
The object would likely not require destructor (you only need a destructor if you need to cleanup resources, e.g. pointers, but if you're serializing a pointer, you're just asking for trouble). It's probably nice to have some syntax sugars constructors, but nothing really necessary.
If the data is just a Plain Old Data (POD) object for carrying data, then it's a candidate for being a struct (fully public class).
However, depending on your design, you might want to consider adding some behavior, e.g. an .action() method, that knows how to integrate the data it is carrying to your actual Model object; as opposed to having the actual Model integrating those changes itself. In effect, the DTO can be considered part of the Controller (input) instead of part of Model (data).
In any case, in any language, a getter/setter is a sign of poor encapsulation. It is not OOP to have a getter/setter for each instance fields. Objects should be Rich, not Anemic. If you really want an Anemic Object, then skip the getter/setter and go directly to POD full-public struct; there is almost no benefit of using getter/setter over fully public struct, except that it complicates code so it might give you a higher rating if your workplace uses lines of code as a productivity metric.
I'm writing a game and an accompanying engine in C++. The engine relies heavily on automation using a simple embedded scripting language. Scripts can create object classes, define event listeners on them, and produce instances from them. At present, an instance must be bound to a script-global identifier in order to preserve its existence. The obvious result of this is that there can be no anonymous objects, which will be by far the most common.
At present, instances are managed using a std::set<Instance*, spatial_sort>, where spatial_sort is a functor that sorts instances by position, for rendering and collision detection. Instances are removed and re-inserted each frame using their current position as a hint, under the assumption that they're not likely to move a whole lot in a fiftieth of a second. If a dead flag is set in the instance, it is erased from the set. The Instance constructors and destructor invoke insert(this) and erase(this), respectively.
In order to allow anonymous instances, I want to change the set to a std::set<boost::shared_ptr<Instance>, spatial_sort>, which would allow Instance to share ownership of instances and preserve their existence until they destroy themselves. Unfortunately, because the calls to insert() need to be placed in the constructor, shared_from_this() won't work for obtaining a shared_ptr to the Instance. It doesn't matter at all that Instance happens to already inherit from boost::enable_shared_from_this<> via its base class.
Can anyone recommend a suitable workaround?
Edit:
I did what I should have been doing in the first place, and split the behaviour of the Instance class into two classes: Instance and Reference. The expression new SomeClass in a script then returns a Reference to a new Instance. The Instance objects themselves are never managed using a shared_ptr, so they are responsible for committing suicide in response to a suitable event, e.g., end of animation, end of level, etc.
Thanks for the help! Refactoring is as good a solution as any if it Just Works.
You could add a static method to Instance that you then use to create new objects and that also does the administrative stuff like adding it to the set:
static Instance* create(int something) {
boost::shared_ptr<Instance> sptr(new Instance(something));
instanceset.insert(sptr);
return sptr.get();
}
If you want to make this the only way to construct an object of this class you could also make the normal constructor private or protected.
For more on this see also the C++ FAQ Lite entry about "Dynamic binding during initialization", which is not directly related but uses the same technique to work around the restrictions on the use of virtual functions in constructors.