How to show a Singleton relationship in a class diagram - c++

If a class contains pointer to a singleton class, can it beaggregation?
To my understanding it cannot be a has-a relationship since the class does not make an instance of the singleton class, it is just using it like association relationship.

The title doesn't make 100% complete sense as written. There are singleton classes, but there aren't really singleton relationships. Any relationship can be assigned a multiplicity at either end, so if you mean one-to-one relationships, all you do is assign multiplicity 1 at both ends.
Classes can also have multiplicities. You don't often see this used, except in one case: singletons.
When it comes to A having or containing or referencing B, there are basically three levels of tightness in UML.
Aggregation (unfilled rhomboid arrow head) implies that the containment is not exclusive and that the contained object does not share any aspect of its lifecycle with the containing object. In implementation, this is typically a pointer.
Composition (filled rhomboid arrow head) implies that the contained object gets destroyed when the containing object does. Getting this to work usually means that the containment is exclusive. In implementation, this is often a pointer whose destructor is called in the destructor of the containing class (although it may not be created in the constructor of the containing class).
Directed association or member attribute (same thing in UML) implies that the contained object is part of the state, or a constituent if you will, of the containing object. In implementation, this typically means that the reference is not a pointer, or if it is that the contained object is co-created and -destroyed with the containing object.
Aggregation of a singleton is perfectly permissible (even from several different classes), because aggregation is by definition non-exclusive.
Composition is a bit iffy, unless the containing class is also a singleton.
Attribute / directed association is most likely wrong. If the containing class is a singleton, it doesn't make any sense to make the contained class a singleton as well since that's implied. And if the contained class is used as a member in two different classes, it cannot be a singleton.
In addition to the above, you can also of course add as many Usage relationships as you wish. This is common in all design, and implies that the class at the source end of the relationship calls methods in the class at the target end.

I would say, technically, yes, you can have a member variable that is a pointer to a singleton object and call it aggregation; using the aggregation term doesn't have much meaning once you write the code though. For all intents and purposes, it is just an association.
However, the use of an aggregation association in a diagram may or may not help a viewer of the diagram to comprehend it. That probably depends on who you are going to show it to and what they might understand aggregation to mean.
To actually answer the question in the title (using info from The UML User Guide (2nd Edition):
______________________ ______________________
| | | 1|
| AggregatingClass | | SingletonClass |
|____________________| 0..1|____________________|
| |<>--------| |
|____________________| |____________________|
| | | |
|____________________| |____________________|
(Note the 1 in the upper right hand corner of the singleton class box indicating cardinality.)

There is also an aggregation with an open square instead of a filled.
The open means the first instance does not make the other (but still has a has-a relationship).

You could pretend that it is aggregation, but truth of it is this: singletons have nothing to do with object oriented code. They are a form of global state (just like global variables are).
You might want to consider a different approach to the problem.
P.S some materials that could help:
Global State and Singletons
Don't Look For Things!

Related

Defining different OnCollide()-s for different objects in component based game engine?

I have a general question, which can be simply explained by this:
I have 2 objects: bullet and human.
Both of these objects have rigidbodies, and I would like to call both of their OnCollide() method on colliding with each other.
My question is, that how can I implement OnCollide() differently (and effectively) for these objects while the only difference between their game objects is their physical respresentation?
Make a Behaviour abstract class, which has an OnCollide method, implement this class by BulletBehaviour and HumanBehaviour class which overrides OnCollide(), then this object's OnCollide will be called in the Rigidbody's OnCollide()?
I don't think that this is a good way of solving the problem. Or is it?

Which way does Inheritace take place inside?

Consider a simple picture below.
Here Child inherit's its properties from both, Parent 1 and Parent 2, and Also the properties directly from the Grand Parent.
Let each be seperate class.
* Its obvious that, to avoid the conflict of child inheriting the properties of parent 1 and parent 2, we make a base class "virtual" .
From, where ever I've learnt I was instructed that in mainfunction, In child class, I could get the properties of parent or grandparent.
I get confused when, I try to think what happens with
Compiler and Memory side internally.
Let display() be the member function of all Grandparent and parent1 and parent2. Now the virtual base class takes necessary steps, to avoid ambiguity in the child which actually has two duplicate sets of parent1 and parent2, yes also the grandparent.
Now, I want to make myself clear that
If the display() of the grandparent is accessed from the child using pointer and addresses internally. child won't be having the any duplicate sets. So, there won't araise any ambiguity therefore why else are we going for virtual funtions?
In other case, What I'm thinking above is wrong, and consider that display() of grandparent is actually or I assume to be copied into the child,and the same should happen with the parent1 and parent2. (Please, don't say that base child will be having access or containing public and protected members of grandparent, parent1 and parent2 , I'm sorry, the reason is that, this is the answer I found on Internet and it doesn't clarify me, when I think how I happens) As a result, child should be having same member function in the same class of child, this should definitely give problems because child couldn't have same member functions as even constructors differ in arguments.
Any other cases are possible, please explain.
I made my maximum effort to detail my doubt.
If possible, help me to understand how exactly the virtual classes and inheritance concepts work.
Thank you.
--
A derived class is composed of everything that the base class is PLUS your extra bits. No copying takes place because a class is just like a design. It's the object where stuff actually exists. When you instantiate the derived class (create an object of it) it will contain members of the derived and base class as one.
Your class is like a blueprint - the design for a house. I could design a house with 1 bedroom, 1 bathroom and a kitchen. This blueprint is like your class. I can't pee in the bathroom yet: it's just a design on paper. I can't make a sandwich in kitchen. Now I can choose to have the house built - this is then an object. Now I can take a pee. It's quite a relief, I had to wait ages. In fact I can make as many copies of this house as I like. Making copies is instantiating more objects.
But one day I think to myself I'd like a bigger house based on this one so I make a new design that I can simply add to the old design extending the house. This is inheritance. My new design has a lounge added on and another toilet (I need to pee a lot, ok?). When I instantiate this version of my design I'll get a house which contains a bedroom from the 1st design, and bathroom, and kitchen as well as my lounge.
Sounds to me like you need to get a good book on object oriented programming. It won't be as amazing as my explanation there, no doubt, and probably won't talk about toilets as much as one would normally like, however it will explain much more than this. Good luck.
An object of a derived type contains within it a subobject of the base type. When you call a non-virtual, non-static member function of the base class, then that function is effectively invoked on that base subobject.
(Note that it is possible to have multiple base subobjects of the same type when you use multiple inheritance.)
Virtual functions behave somewhat differently: a virtual call always requests a (usually dynamic) search for the most-derived object of which the invoked object is a base subobject, and then call the last overrider of the function. But that's essentially unrelated to the point of the question. For example, when you have struct A { virtual void f(); }; struct B : A {}; and then call B().f(), that call is still performed on the A-subobject – the virtual dispatch only starts there.

Inheritance with composition

I am designing a system, I have not yet implemented first I am just diagraming it and then will code it, I want to ask one simple question:
What to do when we are using both inheritance and composition at the same time?
For example, in a hotel, there are 2 kinds of room standard room and Twin room let us say. For this I can use inheritance concept and these 2 kinds of rooms will be derived class but i can also use composition and will make seperate class for standard and twin room, then will use this is my hotel class.
What should I do?
This question is kinda vague and there are many details missing, yet I'll share some ideas...
First thing: while working on design of your application, what matters the most are the requirements.
You need to try to identify entities that will have some meaning in your system first. Let's say you know that there will be Hotel and Room. Note, that this relation is a composition already, mainly because:
room can be part of only 1 hotel, it is not shared among multiple hotels
once the hotel is destroyed, so are all rooms in it
in C++, composition usually means "by value", i.e. class Hotel could have Room room; that would be an object with automatic storage duration with its lifetime tied to the lifetime of instance of Hotel, with multiple rooms you could just put them to the vector yielding the same relationship:
class Room { ... };
class Hotel {
public:
std::vector<Room> rooms;
};
(By the way, an aggregation would be most likely represented by a pointer or reference). This is another good example of composition:
If you know that there will be different kinds of rooms, first questions should be: will these objects have different behaviour? will my system treat them in different way? ...maybe you don't need to go for finer granularity than Room and everything that a concrete room will be specific with will be expressed with its attributes - size, number of beds, maybe dozens of boolean "has" flags ("has aircon", "has TV", "has microwave", ...), maybe all of its properties can be expressed with simple "type", values of which you would put into the enum.
I the case you site, I would have a room_type property on the room class, and I would set the type of the room_type property to an enumerated type with possible values of STANDARD and TWIN.
As long as there are not significant behavioral differences depending upon this type field, I would keep it simple.
If there are complicated behaviors, like predicting clean up based upon number of beds, changing pricing, and so on, I would use an abstract base class CRoom, and inherit CStdRoom and CTwinRoom from that, possibly setting a constant num_of_beds property in the class constructors.
You shouldn't use language inheritance to model business requirement inheritance. It just makes it too hard to modify or extend the business model. Language inheritance is for implementing features of your model, not the model itself.
Instead, derive all your objects from 'business object' or similar, to encapsulate common internal behaviour such as serialisation. Your classes can have types and you can use typeinfo, or you can use an explicit type field. Either way links between objects, whether inheritance-like or composition-like should be pointers (or index id fields) and collections (of pointers or index ids). [Your code snippet is fine, but pointers complicate memory management which integer ids avoid.]
Complicated behaviours should belong to other classes such as the Pricing, Cleaning, etc. There are other patterns to use in setting the relationships between business objects and business actions, but again avoid crystallising them using language features. You will regret it, if the system grows or changes even a bit.

C++: Recommendations for Member Function Access at the Same Architecture Layer

I have 4 classes of the following hierachy:
MyTop
|
-------------------
| | |
BlockA BlockB BlockC
BlockA, BlockB, and BlockC are the composed objects of MyTop. BlockA provides a function LookUpTable(), and BlockB and BlockC now need to access the look-up table owned by BlockA. What is a good (or at least typical) practice for BlockB and BlockC to access the look-up table?
I thought about implementing the look-up table as a class itself, but the content of the loop-up table is slightly coupled with the initialization of BlockA, and it may not be trivial to decouple the table from BlockA (it's still doable, but not preferred). Right now my solution is to pass the request from BlockB and BlockC to MyTop, and let MyTop to manage the communication between the blocks. However, it doesn't seem a good way to handle the problem when there are more blocks that need access to the look-up table in BlockA. I wonder if this is a well-known problem and already has a "best practice" solution to it. Thanks!
I thought about implementing the
look-up table as a class itself, but
the content of the loop-up table is
slightly coupled with the
initialization of BlockA, and it may
not be trivial to decouple the table
from BlockA (it's still doable, but
not preferred).
Can't you simply make BlocA intialize that look-up table owner object? It would be a singleton (if it's correct in your case) with BlocA as friend class to be sure it's the only one to access initialization (construction?) functions.
I don't know if there's a general solution but there definitely is a general advice: tell, don't ask.
From what I can see you are trying to access the data of BlockA that is stored in a lookup table and then perform some operation on them. This is violation of the encapsulation principle where only the object holding the data should access and modify it.
A better way would be to extract the lookup table functionality into a class and add common methods for all three blocks. Then create three subclasses of the lookup table class and add methods that will be used only by specific blocks (if there are any such methods). In BlockA, BlockB and BlockC use these classes. This allows a more loose coupling than accessing a lookup table stored directly in BlockA.
With the current mechanism, BlockB and BlockC consumes the facility provided in BlockA. My understanding is that it makes it different from BlockA. They are not on par.
BlockA, BlockB, BlockC inherits the methods of MyTop.
So LookUpTable() a method of MyTop.
It should access a object attribute which is initialized only when you instantiate BlockA.

References vs information hiding C++

I need suggestions on how to solve the type of problems described below. I'm fairly new at C++ and OO-design.
I've learnt:
Pointers shall be avoided when ever they can be replaced by references.
Objects shall have no knowledge of objects that they don't need to know about.
But when creating objects having references to other objects we must pass these references as input arguments to the constructor. Thus we need to know about objects we should not not know anything about.
But look at the following example:
Suppose I have a object "Menu" that needs to have it's own timer object "Timer". I'd like to implement this association as a reference.
The object MenuHandler aggregates a lot of Menu objects but shall not have any knowledge about Timer objects. But when the MenuHandler creates a Menu object it must pass a Timer reference argument to the constructor. Thus, ****MenuHandler** must know about **Timer****.
Any suggestions on how to treat these kind of problems?
I'd hesitate to bless your choice of words when it comes to the two numbered points. They're a sign you're on the right way learning C++, but they might be misleading to other novices. When I take a look at your concrete examples, this becomes more obvious.
A MenuHandler should not create menus. The content of menus is determined by by the application, so the application object (or the Controller part, if you've implemented Model-View-Controller) should create menus. The MenuHander merely takes ownership of menus created elsewhere.
Also, it may make sense to give each menu its own timer. That means the relation can be described as "Has a"; the menu has a timer. The relationship usually implmented by references can be described as "Knows a" (the inheritance relationship is usally called "Is a"). If each Menu object has a Timer, it can be a member, and initialized by the Menu constructor(s). The Timer object internally may obtain a reference to the system clock in its constructor, but that's not your concern.
Why not simply make the Timer object a member (by value) of the Menu class?
I find that I produce better (more maintainable, faster, etc) code and that I'm more productive using references in C++ than I would be solving the same problem with pointers... I think the traditional answer to your example would be to have a factory object that creates menus. In this way, the MenuHandler doesn't need to know about the Timer class.
The MenuHandler creates a Timer object, passes it into the Menu constructor, and forgets about it. That seems entirely reasonable.
If the MenuHandler unnecessarily kept a reference to the Timer, that would be against the advice point #2.
In a more general case where you need to provide a class to another class in order to do some kind of callback, you avoid mutual dependency (both know each other) by using an interface.
Class A derives from the interface. Class B accepts the interface as paramater in the constructor and calls the virtual function from that interface when needed.
Also check the observer design pattern.
For #1 Be very careful with the lifetime of your objects. References are no that suitable to handle dynamic graph of objets ( like your menu, menuhandler, timer, etc... ). What if you want to change the timer object later ?
It's not a good idea to have references as members in a class if the lifetime of referenced objects is not really known.
Avoiding pointer does not mean using references everywhere, you should have a look at smart pointers which will be more suitable for what you want to do.