class relationships UML diagrams - c++

I have my class structure as follows
add.h has class add that has method int add(int,int) and add.cpp includes add.h and defines method add above
sub.h has class sub that has method int sub(int,int)
and sub.cpp includes sub.h and defines method sub
now, main.h has class main and it includes add.h and sub.h; main class also has some print methods to print results;main.cpp uses method add and sub to do calculations
My question is, what is the relationship between class main & class add also class main & class sub. Main.h simply includes add.h and sub.h, so is there any name for this relations.
AFAIK It is not inheritance, it is not compositon or aggregation.

You are mixing up the concepts of C++ compilation and class relationships - the two things really have nothing to do with each other. In the event that you want to model the relationships between the C++ source files, you should use a UML Component Diagram, but few people bother with this.

You have 3 independent classes. main will only use add and sub in its implementation. I don't see any relation between them.

As Neil says: the source files (and header files) happen to coincide with the classes here. That means that you don't model the relation between a.cpp and a.h: it's the declaration and the definition of class a, and the fact that they're separated is no design issue, merely a compilation artifact.
In general, when a .cpp file includes a .h file not of it's own class, you can say that the .cpp uses what's in the .h. When class a's declaration needs class b's declaration, probably a is aggregating class b.
In this case, I would say that the (plain, one-directional) relation between main and the 'operations' is to be labeled as 'usage'.
Next to that, it's common to give the sub and add classes a common superclass/interface.

Related

Weird C++ design pattern: Class inheritance via include files

I came across a C++ coding pattern that is so weird that I'd really like to know where it comes from. Some classes (base classes, no ancestors) need to share certain functionality. Normally you would implement this as an ancestor class (a template if need be) from which those classes inherit which need the functionality.
Here, the programmer chose to pack the required method and data member declarations into a separate file and include this file in midst of the class declaration. They even #define'd a symbol to the name of the class being defined before the #include line. This created declarations like this:
class CMyStructure
{
public:
CMyStructure();
~CMyStructure();
__int64 m_SomeData;
double m_SomeOtherData;
#define DEFINE_CLASS CMyStructure
#include "include_definitions.h"
#undef DEFINE_CLASS
};
The included code made use of the DEFINE_CLASS symbol.
The same pattern is repeated in the implementation file, where a different file is included which defines some methods.
Does this pattern have a name? Where does it come from?
(A warning to C++ newbies: Don't use this pattern!)
Thanks, Hans

Inheritance and Includes

Lets say I have 2 classes. One is BaseClass and one is DerivedClass, being a derived class of BaseClass. I need to be able to create objects of both classes in another file. By using an #include statement to include the derived class in the new file, I have access to the derived class directly and the base class indirectly (as the derived class includes it in its file). Is it better to use this method of indirect "access" to the base class, or would it be better to directly include it alongside the derived class in the file?
The general advice is include what you use.
If you are coding to an API specification, and that specification does not explicitly detail the base-derived nature of the classes, then any changes to that relationship may break the includes that the files you depend on use.
See here as well.
If you are certain the BaseClass will always the base to the DerivedClass, then there may be little need include both, but for clarity, I would go ahead and do it anyway, it shows your intent.
Including all needed headers instead of relying on transitivity gives has two advantages:
If your header files will be refactored, you will not need to change your cpp file.
It clearly identifies your intent for other developers.

Access Derived Class When Only Base Class Header is Included

I'm trying to understand if there is a way set an include directive for a base class but also be able to access derived classes that are defined in a different header than the base class. For instance:
In GenericObject.h:
class GenericObject {
/* whatever - shared properties and methods implemented in .cpp file */
}
In Ball.h:
class Ball : public GenericObject {
/* whatever - implementation details are in the .cpp file */
}
Now in some other implementation file (let's call it the main.cpp), I have #included "GenericObject.h". In main.cpp, I want to be able to access both the members of the GenericObject class as well as the Ball class and any other derived class of GenericObject. From my trials so far, the compiler won't recognize the Ball identifier if I try to declare it like Ball * b; and thus any of the members that belong to its class.
Is this because my #include'd "GenericObject.h" file is not also linking that there is this derived Ball class for me to access? I can correctly ID and use the Ball class if I "#include "Ball.h" but I can't imagine I should include all of the header files of derived classes of the GenericObject class, right?
If I had to take a guess at how this might work, I'd guess that something like a prototype declaration for the Ball class inside the GenericObject class would be a step in the right direction but I'm not sure if a class prototype is even a thing.
Thanks for reading and any feedback everyone!
No, you can't use any identifier that's not yet described. This includes any class, whether it derives from a base or not.
It seems to me you are violating Liskov. If you receive a reference or pointer to a base then you should not be doing anything that requires you know that there is a derived or not. You should only be using the interface of the base. Thereby you no longer need to include the headers for derived classes where you're not using something defined only in THEIR interface.
I can't imagine I should include all of the header files of derived classes of the GenericObject class, right?
If you want to access any class derived from GenericObject, other than through a pointer or a reference, you will need to #include the header file for them.
If you can get by with using just pointers and references, you don't need to #include the header files but you still have to forward declare them.

C++ and UML diagrams

Let be A and B class such that are which inherit of C class. All are in a file.cpp together with method main of the Main class. If I want create a instance of the classe A then ...
file.cpp
class C{
}
class A : public C{
}
class B : public C{
}
class Main{
.
.
.
void main(){
C *c = new A();
}
}
Where a diagram UML is
Now, Suppose I have the same classes but each class in a different file. If I want to instantiate the class A, as above, I would have insert an #include A.h directive in the Main class which would bring up a dependency in my diagram:
My question is: Which case is correct if I wanted to do the same? or I am interpreting wrong the relations UML in C++?
First off, you should not put code in .h files unless you know what you are doing (see inline functions, mainly used for speed)
Then in main.h, you don't need any reference to A. In main.cpp however, you will need to include A.h. Remember that UML is language agnostic, it is used to draw "who talks to who" rather than "who compiles with who".
More often than not, your c++ compiler will generate an output file (with gcc these are .o files, Visual Studio also does this but transparently) for each cpp file. All output files will then be merged together (most of the time) in your application or library and only then will your function be linked together.
You might also want to take a look at forward references. It is to tell the compiler (not the linker) that "this class does exist, you might not know about it right now, but I swear to God, it WILL exist in the linker output blob".
In your particular case, I would draw the class diagram like your second example, regardless of whether you use only one or multiple cpp files. Your Main class DOES know about A.
Now imagine that your C class have methods like
A* C::createA()
{
return new A;
}
B* C::createB()
{
return new B;
}
Then your main class would have
int main()
{
C* instance1 = C::createA();
C* instance2 = C::createB();
}
In that case, your main class would lose all intimate knowledge of A and B, conforming to your first diagram. This would of course create more coupling between A, B and C, which brings its own problems but is closer to a factory pattern
I don't think its required to have the has-a relationships as in the second diagram because it is implied.
A is-a a C, B is-a C and Main has-a C.
Its more about the structure of your design than the includes in your files.
You need to use the composition relationship to show that Main has-a instance of C.
I have never documented which files need to be included, as it is assumed that if you need functionality of a class that lives in another file, you're probably going to need an include.
EDIT: Actually, there is no composition, as it seems you Main class has a methods called main() that creates an instance of the C class, and is not a member itself.

C++ project layout

I am completely confused as to the proper way to layout a C++ project.
I had all my classes in separate .cpp files, with their definitions in .h files. I then had one "header.h" which contained all the class headers, external dependencies and a few other things. But I wasn't able to use class names in the header files, where I needed to declare a pointer to one.
Can someone please explain the proper object-orientated layout for a C++ project.
You can fix the problem "wasn't able to use class names in the header files, where I needed to declare a pointer to one" by using forward class declarations, like:
class myClass;
However, having every class include a header.h that then includes every class is overkill. Instead, you should have each class specifically include only the classes and external dependencies that it actually needs.