getting to know classes in C++ better [closed] - c++

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have taken several classes now in C++ and a little bit of python. And a common thing that keeps coming up is my failure to really understand whats going on when you are creating a class. I was wondering if someone could either explain the specifics as far as classes in C++ are concerned or least point me to websites that go into great detail. I know the declaration but as far as what is going on with accessors, methods, constructors and destructors and even if you'd like to go as far as define when and why would the best time to use a class. I just need overall clarification. Thanks!

In programming, you have data and functions that manipulate that data. A structure (struct) allows you to group related pieces of data into one logical object.
A class allows you to group data and functions together as a single unit. Thus, instead of saying matrix_add(m1, m2), you can say m1.add(m2). The data and functions can be private (only accessible to the class), protected (accessible to the class and its children) or public (accessible to anyone). This is called encapsulation: typically, the data is private and is accessible via a set of public functions. In C++, a struct defaults to public scope and a class to private scope, but are otherwise identical.
An accessor is the name of a function that typically provides acccess to the private data of a class. These can be getters that return (or get) the data, or setters that modify (or set) the data. Typically, these methods check the input for validity to ensure internal constraints hold. Note that an accessor may not directly return private data, but derived properties; that is, size and empty on C++ containers (vector, list, ...) could be thought of as accessors even though these could be computed values.
A constructor is a special function that allows the class to initialize the data to sane values, or allow the user to create a new object of the class with potentially different data. For example, a rectangle class could be constructed from another rectangle, a point and size, a set of top/left/bottom/right values or could be empty. In C++, the constructor has the same name as the class; in python this is called __init__.
A default constructor is a constructor that takes no parameters and initializes the class to its default state (e.g. an identity matrix for a matrix class).
A copy constructor is a constructor that takes another object of the class type and creates a copy of it. This allows allocated memory to be handled properly (e.g. for string and vector classes). With a simple data structure the objects are copied by value, so the two objects would reference the same memory.
A destructor is a special function that allows the class to perform cleanup. This could be things like deleting any allocated memory, releasing locks on mutexes or closing open file handles. In C++, a destructor has the same name as the class but with a ~ in front of it, e.g. for a matrix class the destructor would be ~matrix.
A method is just a function that is a part of a class. Each method takes the class object being operated on as the first parameter. When declaring methods, C++ does this internally for you (providing an implicit this argument) while python requires you to provide the parameter explicitly.
In C++, an operator is a special function that is used to implement e.g. +, -, * and /. This allows you to create classes that can be used like built in types (esp. for mathematical classes like vectors, matrices, complex and rational numbers).
A class (the "derived" class) can inherit from another class (the "base" class). Here, the derived class is a child of the base class and can access any protected data or methods. This is called inheritance. These form a class heirarchy.
A class can be constructed to have virtual methods that can be overriden by derived classes. This is called polymorphism.
You can declare virtual methods that do not provide any implementation. These methods are called pure virtual methods and the classes that provide them are known as abstract base classes. Here, the derived class needs to implement these methods, while with non-pure virtual methods the derived class does not need to implement the method.
A class that only has pure virtual methods (no other methods) is effectively an interface class. C++ does not have any special notation for this, whereas other languages do.
Interfaces are typically used to interact between two or more different systems. For example, a music player could provide a plugin architecture that allows plugins to extend the supported audio formats it can handle. Here, the interface(s) provide the contract between the player and plugin.

Think of objects as "smart" structures which not just contain data but also the code to manipulate that data. Think of classes as type definitions for these "smart" structures.
Creating a class instance is just like creating a variable of a structure type. Calling a member function of a class is just like calling a normal function, and passing the structure to it as a parameter with the name "this".
When you understood this, you already understand most about what object-oriented programming is all about.
By the way: Do you know what's the difference between the keywords struct and class in C++? In a struct, all members are public by default and in a class all members are private by default. That's it. Otherwise structs and classes are the same thing. When you explicitely declare all members as private, public or protected, you can switch them out and the program will compile and work just like before.

And a common thing that keeps coming up is my failure to really understand whats going on when you are creating a class.
I'm answering this part as others have answered the second part, code below is java however, looking at the code kindly give importance to class concept than Java constructs.
Well, before jumping into the CLASS thing in the programming world. Lets take a look a the real world. If we look around us we see many elements [rocks, animals, humans, plants etc] in our living echo system. Careful observation finds that, they have some common features that can be grouped together [Life, Organs, Color etc] , lets call this common grouping by a technical name called "CLASS".
In order to understand, classes in programming world one should understand why there is such a construct called class. Main fact is the it is part of a programming paradigm called Object Oriented Programming, where, programmers try to map real world objects say Vehicles, Banks, etc into programming models called Objects. In order to create these object, we have to create a construct that can actually describe those objects. Such a construct is called a class.
Below explanations goes beyond just Classes for completeness.
Lets look at a technical example Circle, Rectangle, Square, Hexagon, looking at them we find that they belong to a common CLASS called SHAPE.
Don't get carried away by details [extends, #Override etc] in the example below. It explains simple concept of classing how it is exploited to make new classes. Once a class is created, it is just a skeleton ie it is not allocated any memory for a real use. In order to make a class useful, we create its objects. So objects are 'elements' with different states for same class.
Say for circle objects, obj1, obj2, each object have different radius.
class Shape {
String name;
int color;
public Shape(String name, int color) {
this.name = name;
this.color = color;
}
String getName() {
return name;
}
int getColor() {
return color;
}
double getArea() {
return 0;
}
double getPerimeter() {
return 0;
}
}
class Rectangle extends Shape {
int l, b;
public Rectangle(int l, int b, int h, int color) {
super("Rectangle", color);
this.l = l;
this.b = b;
}
/* Overloading */
#Override
double getArea() {
return l*b;
}
/* Overloading */
#Override
double getPerimeter() {
return (2*l + 2*b);
}
}
class Circle extends Shape {
int r;
public Circle(int r, int color) {
super("Circle", color);
this.r = r;
}
dobule getArea() {
return (PI * (r*r));
}
double getPerimeter() {
return (2*PI*r);
}
}

Related

Determine real type of base pointer in a big hierarchy without dynamic_cast

Suppose, that I have an abstract base State class and at least two derived classes AnimalState and PlantState(also abstract). Also, I have many derived classes from AnimalState and PlantState.
class State{} // abstract
class AnimalState: public State{} // abstract
class PlantState: public State{} // abstract
//maybe few more of such classes here
class AnimalStateSpecific1: public AnimalState{}
class AnimalStateSpecific2: public AnimalState{}
... //many of them
class PlantStateSpecific1: public PlantState{}
class PlantStateSpecific2: public PlantState{}
... //many of them
Now suppose, that I use them in some kind of method that operates on base State pointers. Those pointers are replaced over time with other pointers to different class from the State hierarchy. It happens by some rule, specifically within the predefined state graph.
Now to the question part. In order to determine the next state, I need to know the previous one. But since I have only base State pointers, I can not efficiently tell what type of state I have, without doing dynamic_cast to every derived class in the hierarchy that is not good. I can have some enum with all kinds of states that I have, but I do not really like that because I do not want to mix information from two hierarchy branches, as it is really different. Also, I do not like different enums for every branch in the hierarchy such as AnimalStateEnum, PlantStateEnum etc.
What is the best solution for this problem? Maybe my design is not good from the start? I want to keep it as generic as possible and work only with base class objects, if possible.
Now to the question part. In order to determine the next state, I need to know the previous one.
Simplest solution based on limited information we have - object, which knows it's own state creates next state object:
class State{
public:
...
virtual std::unique_ptr<State> transform( some data ) = 0;
};
then you implement it in each derived from State class which can change it's state and knows where it can move to. What data you need to pass is not a simple question - it depends on your task and may have various options, but you need to define something that can be used by all derived classes, as signature is defined on the base class and shared on all derived ones.
What is the best solution for this problem? Maybe my design is not good from the start?
This question is not trivial and only can be answered having pretty deep knowledge on your task. If you are unsure - implement a prototype and check if solution fits your problem well. Unfortunately the only way to learn how to create a good design is your own experience (except trivial cases of course).
You could simply have a virtual method next() inside the state class hierarchy,
and then do something similar to the following example:
State *globalState = nullptr;
void foo(State *s)
{
globalState = s->next();
}
Where each derived class will implement next() to its own meaning:
PlantStateSpecific1 *AnimalStateSpecific1::next(){ return new PlantStateSpecific1; }
AnimalStateSpecific1 *PlantStateSpecific1::next(){ return new AnimalStateSpecific1; }
This is more OOP than having an enum / integer descriptor of the derived class.
What you can have is an integer inside the base state class that every class below it will set in its constructor. Then you can either use a sereis of constants, a list of possible states with the id corresponding to the state type index, or use an enumerator.
The id is more flexible as you can create state types with relative ease and add handling to them without too much difficulty, aswell as if you want to create a new state from the id type.
Just one of the ways iv done this before, but there are probably many others.

How to create a class which uses member functions defined in another class C++

I'm new to object oriented programming and am struggling a bit with how best to write classes.
I am trying to abstract the idea of sorting to objects that are not just lists of numbers. I have an abstract base class, SortableContainer, which contains all the necessary virtual functions for comparing and swapping elements, along with some overloaded operators. I then have two classes derived from that, MVector and CoordinateArray. Both of these derived classes have proper definitions for all the virtual functions in the base class. Everything up to this point has worked just fine. MVector just stores vector-like objects and CoordinateArray stores vectors of coordinates onto which a notion of 'less than' has been defined.
My problem now is that I have created a new class, Life, which I want to use to implement the game of life using a CoordinateArray object to store the alive cells. The outline of my Life class looks like this:
class Life
{
public:
CoordinateArray LiveCells;
Life();
};
When I create a Life object and initialise it with the coordinates of some alive cells, none of the member functions defined in the CoordinateArray derived class will work. How can I fix this? Do I have to derive the Life class from the SortableContainer class and then override all the pure virtual functions? Any help or direction to help will be much appreciated.
To answer your question simply and in a pragmatical way, yes, if you want your Life object to have some member functions they need to come from somewhere, the most straight forward way is to derive it from a class containing those member functions, composition does not transfer members to the owner, inheritance does that:
class Life : public CoordinateArray
{
public:
Life();
};
Now you can use your Life objects as a CoordinateArray object. If anything is pure virtual in the parent class you will indeed need to implement it in the derived class, but even if something is not you can still reimplement it in the child class to overwrite the parent behaviour.
I avoided conception and design problematics on purpose, this is mainly a technical answer, judging this from a design point of view requires more context and has some subjective side too so that's another story altogether.
It would be useful to see the declaration of CoordinateArray. However, I suspect you need to make public methods in CoordinateArray. If the methods are declared private (i.e., they come after private: in your class declaration), then they can only be used inside the class's own scope. If they're declared public (underneath public:), then they can be used in any scope. (As a sidenote, there is one other classification, protected, which means they can be used by the class and any of its subclasses.)
In order to initialize co-ordinates of some live cells declare the class CoordinateArray LiveCells public to Life
class Life::public CoordinateArray{ }

Design a better API interface to pass a struct from one class to another class [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I am a strong believer of the following design philosophy:
1> Services should be implemented as close as possible where the data is stored.
2> Getter and Setter are evil and should be used carefully.
I rather NOT argue above two arguments here and assume they have their edges.
Here is the challenge I am current facing. I have two classes (i.e AComputer and A) where AComputer provides some services for A and A holds all fundamental data members.
Fact: I am not allowed to combine AComputer inside A due to the system design. I knew, it has broken my point 1> where computation should stay with data.
When passing data from A to AComputer, we have to pass 10(approximately) individual parameters and so it is better to design a structure to do that otherwise the constructor list will grow crazy. Most of the data stored in AComputer are direct copies those of stored in A. We chose to store those data inside AComputer because other functions in AComputer also need those variables.
Here is the question( I am asking for best practice considering API maintenance & modification):
1> Where should we define the pass-structure PassData?
2> Should we provide getter/setter for struct PassData?
I have provided a sample code as follow to illustrate my question in details. It is best that I can find a real work open-source API that has addressed the same issue so that I can learn from it.
If you look at private PassData m_data; defined in class AComputer, I do this in purpose. In other words, if we change the underlying implementation of AComputer, we can replace PassData m_data; with individual variables or something else but NOT break the interface of PassData.
So in this design, I do NOT provide a getter/setter for the struct PassData.
Thank you
class AComputer
{
public:
struct PassData
{ // int type just used as an illustration. Real data has different types,
// such as double, data, string, enum, etc.
// Note: they are not exact copies of variables from A but derived from them
int m_v1;
// from m_v1 to m_v10
//...
int m_v10;
};
// it is better to store the passed-in data since other functions also need it.
AComputer(const PassData& pd) : m_data(pd) {}
int GetCombinedValue() const
{ /* This function returns a value based the passed-in struct of pd */ }
private:
PassData m_data;
};
class A
{
private:
int m_i1;
// from m_i1 to m_i10
// ...
int m_i10;
// from m_i11 to m_i20
// ...
int m_i20;
boost::shared_ptr<AComputer> m_pAComputer;
public:
A()
{
AComputer::PassData aData;
// populate aData ...
m_pAComputer = boost::shared_ptr<AComputer>(new AComputer(aData));
}
int GetCombinedValue() const
{
return m_pAComputer->GetCombinedValue();
}
};
I think it is better clarify a couple of points before start, you said:
If you look at private PassData m_data; defined in class AComputer, I
do this in purpose. In other words, if we change the underlying
implementation of AComputer, we can replace PassData m_data; with
individual variables or something else but NOT break the interface of
PassData.
This is not true, PassData is part of your interface! You cannot replace PassData without breaking client code, because you require PassData in the constructor of AComputer. PassData is not implementation details, but it is pure interface.
Second point that needs clarification:
2> Getter and Setter are evil and should be used carefully.
Correct! But you should know that a POD (Plain-Old-Data struct) is even worst. The only advantage of using a POD instead of class with getter and setter is that you save the trouble to write the functions. But the real issue is still open, the interface of your class is too cumbersome and it will be very difficult to maintain.
Design is always a trade-off between different requirements:
A false sense of flexibility
Your library is distributed and a lot of code is using your class. In this case a change in PassData will be dramatic. If you can pay a small price in runtime you can make your interface flexible. For example the constructor of AComputer will be:
AComputer(const std::map<std::string,boost::any>& PassData);
Have a look at boost::any here.
You may also provide a factory for the map, in order to help the user to create the map easily.
Pro
If you do not required a field any more the code is unchanged.
Cons
Small runtime price.
Lose the compiler type safe check.
If your function requires another mandatory field you are still in trouble. The client code will compile but it will not behave correctly.
Overall this solution is not good, at the very end it is just a fancy version of the original one.
Strategy Pattern
struct CalculateCombinedValueInterface
{
int GetCombinedValue()=0;
virtual ~CalculateCombinedValueInterface(){}
};
class CalculateCombinedValueFirst : CalculateCombinedValueInterface
{
public:
CalculateCombinedValueFirst(int first):first_(first){}
int GetCombinedValue(); //your implementation here
private:
//I used one field but you get the idea
int first_;
};
The client code will be:
CalculateCombinedValueFirst* values = new CalculateCombinedValueFirst(42);
boost::shared_ptr<CalculateCombinedValueInterface> data(values);
Now, if you are going to modify your code, you shouldn't touch already deployed interface. The Object Oriented solution for this is provide a new class that inherites from the abstract class.
class CalculateCombinedValueSecond : CalculateCombinedValueInterface
{
public:
CalculateCombinedValueFirst(int first,double second)
:first_(first),second_(second){}
int GetCombinedValue(); //your implementation here
private:
int first_;
double second_;
};
The client will decide if upgrade to the new class or to stay with the existing version.
Pro
Improve your interface without break client code.
You are not touching existing code, but you introduce new functionality in a new file.
You may want to use the template method design pattern if you want a smaller granularity control.
Cons
Overhead of using virtual functions (basically few picoseconds!)
You cannot break existing code. You have to leave the existing interface untouched and add a new class to model different behavior.
Number of parameters
If you have a set of ten parameters input in one function, it is very likely that these values are logically related. You may collect some of these values in classes. Those classes may be combined in another class that it will be the input of your function. The fact that you have 10 (or more!) data members in a class should ring a bell.
The single responsibility principle said:
There should never be more than one reason for a class to change.
The corollary of this principle is: your class has to be small. If your class has 20 data member is very likely that you will find a lot of reason to change it.
Conclusion
After you have provided an interface (any kind of interface) to the client you cannot change it (a good example are all the deprecate features in C++ that compilers need to implement for years). Pay attention at the interface that you are providing even implicit interface. In your example, PassData is not implementation details but it is part of the class interface.
The number of parameters is a signal that your design needs to be reviewed. It is very difficult change a big class. Your classes should be small and depend to other classes only via an interface (abstract class in C++ slang).
If your class is :
1) small and with just one reason to be changed
2) derived from an abstract class
3) other classes refer to it using a pointer to the abstract class
Your code can be changed easily (but the already provide interface has to be preserved).
If you do not fulfill all these requirements, you will be in trouble.
NOTE: requirements 2) and 3) can change if instead of provide dynamic polymorphims the design is using static polymorphims.
You might consider refactoring to use a pattern object--this object's sole purpose would be to contain the parameters for the method call. For more detail: http://sourcemaking.com/refactoring/introduce-parameter-object
In a normal class design, all member function have the this pointer passed as an implicit parameter so that they can access the data members:
// Regular class
class SomeClass
{
public:
// will be name-mangled by the compiler as something like:
// void SomeClass_getValue(const SomeClass*) const;
void getValue() const
{
return value_; // actually: return this->value_;
}
private:
int value_;
};
You should mimic this as much as possible. If for some reasons you are not allowed to merge the AComputer and A classes into one clean class, the next best thing would be to let AComputer take a pointer to A as a data member. In every member function of AComputer, you would then have to explicitly use the getter/setter functions of A to access the relevant data members.
class AComputer
{
public:
AComputer(A* a): p_(a) {}
// this will be mangled by the compiler to something like
// AComputer_GetCombinedValue(const Acomputer*) const;
int GetCombinedValue() const
{
// in a normal class it would be: return m_i1 + m_i2 + ...
// which would actually be: return this->m_i1 + this->m_i12 + ...
// the code below actually is: return this->p_->m_i1 + this->p_->m_i2 + ...
return p_->get_i1() + p_->get_i2() + ...
}
private:
class A;
A* p_;
};
class A
{
public:
// setters and getters
private:
// data only, NO pointer to AComputer object
}
So in effect, you have created an extra level of indirection that creates the illusion to users that AComputer and A are part of the same abstraction.
Using PassData instead of 10 arguments is good if you have total control of all AComputer clients. It has two advantages: you need to make fewer changes when you add another piece of data to pass, and you can use assignment to struct members on the caller site to make meaning of each "argument" clear.
However, if other people are going to use AComputer, using PassData has a serious drawback. Without it, when you add 11th argument to AComputer constructor, the compiler will detect an error for users who did not update the actual argument list. If you add 11th member to PassData, the compiler will silently accept the structure where the new member is garbage, or, in the best case, zero.
In my opinion, if you use PassData, having getters and setters would be an overkill. "C++ Coding Standards" by Sutter and Alexandresku agrees with that. Title of item #41 is: "make data members private, except for behavourless aggregates (C-style structs)" (emphasis is mine).

Can someone explain the benefits of polymorphism?

So I understand pretty much how it works, but I just can't grasp what makes it useful. You still have to define all the separate functions, you still have to create an instance of each object, so why not just call the function from that object vs creating the object, creating a pointer to the parent object and passing the derived objects reference, just to call a function? I don't understand the benefits of taking this extra step.
Why do this:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
Parent* bar = &foo;
bar->function();
return -3234324;
}
vs this:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
foo.function();
return -3234324;
}
They do exactly the same thing right? Only one uses more memory and more confusion as far as I can tell.
Both your examples do the same thing but in different ways.
The first example calls function() by using Static binding while the second calls it using Dynamic Binding.
In first case the compiler precisely knows which function to call at compilation time itself, while in second case the decision as to which function should be called is made at run-time depending on the type of object which is pointed by the Base class pointer.
What is the advantage?
The advantage is more generic and loosely coupled code.
Imagine a class hierarchy as follows:
The calling code which uses these classes, will be like:
Shape *basep[] = { &line_obj, &tri_obj,
&rect_obj, &cir_obj};
for (i = 0; i < NO_PICTURES; i++)
basep[i] -> Draw ();
Where, line_obj, tri_obj etc are objects of the concrete Shape classes Line, Triangle and so on, and they are stored in a array of pointers of the type of more generalized base class Shape.
This gives the additional flexibility and loose coupling that if you need to add another concrete shape class say Rhombus, the calling code does not have to change much, because it refers to all concrete shapes with a pointer to Base class Shape. You only have to make the Base class pointer point to the new concrete class.
At the sametime the calling code can call appropriate methods of those classes because the Draw() method would be virtual in these classes and the method to call will be decided at run-time depending on what object the base class pointer points to.
The above is an good example of applying Open Closed Principle of the famous SOLID design principles.
Say you want someone to show up for work. You don't know whether they need to take a car, take a bus, walk, or what. You just want them to show up for work. With polymorphism, you just tell them to show up for work and they do. Without polymorphism, you have to figure out how they need to get to work and direct them to that process.
Now say some people start taking a Segway to work. Without polymorphism, every piece of code that tells someone to come to work has to learn this new way to get to work and how to figure out who gets to work that way and how to tell them to do it. With polymorphism, you put that code in one place, in the implementation of the Segway-rider, and all the code that tells people to go to work tells Segway-riders to take their Segways, even though it has no idea that this is what it's doing.
There are many real-world programming analogies. Say you need to tell someone that there's a problem they need to investigate. Their preferred contact mechanism might be email, or it might be an instant message. Maybe it's an SMS message. With a polymorphic notification method, you can add a new notification mechanism without having to change every bit of code that might ever need to use it.
polymorphism is great if you have a list/array of object which share a common ancestor and you wich to do some common thing with them, or you have an overridden method. The example I learnt the concept from, use shapes as and overriding the draw method. They all do different things, but they're all a 'shape' and can all be drawn. Your example doesn't really do anything useful to warrant using polymorphism
A good example of useful polymorphism is the .NET Stream class. It has many implementations such as "FileStream", "MemoryStream", "GZipStream", etcetera. An algorithm that uses "Stream" instead of "FileStream" can be reused on any of the other stream types with little or no modification.
There are countless examples of nice uses of polymorphism. Consider as an example a class that represents GUI widgets. The most base classs would have something like:
class BaseWidget
{
...
virtual void draw() = 0;
...
};
That is a pure virtual function. It means that ALL the class that inherit the Base will need to implement it. And ofcourse all widgets in a GUI need to draw themselves, right? So that's why you would need a base class with all of the functions that are common for all GUI widgets to be defined as pure virtuals because then in any child you will do like that:
class ChildWidget
{
...
void draw()
{
//draw this widget using the knowledge provided by this child class
}
};
class ChildWidget2
{
...
void draw()
{
//draw this widget using the knowledge provided by this child class
}
};
Then in your code you need not care about checking what kind of widget it is that you are drawing. The responsibility of knowing how to draw itself lies with the widget (the object) and not with you. So you can do something like that in your main loop:
for(int i = 0; i < numberOfWidgets; i++)
{
widgetsArray[i].draw();
}
And the above would draw all the widgets no matter if they are of ChildWidget1, ChildWidget2, TextBox, Button type.
Hope that it helps to understand the benefits of polymorphism a bit.
Reuse, generalisation and extensibility.
I may have an abstract class hierarchy like this: Vehicle > Car. I can then simply derive from Car to implement concrete types SaloonCar, CoupeCar etc. I implement common code in the abstract base classes. I may have also built some other code that is coupled with Car. My SaloonCar and CoupeCar are both Cars so I can pass them to this client code without alteration.
Now consider that I may have an interface; IInternalCombustionEngine and a class coupled with with this, say Garage (contrived I know, stay with me). I can implement this interface on classes defined in separate class hierarchies. E.G.
public abstract class Vehicle {..}
public abstract class Bus : Vehicle, IPassengerVehicle, IHydrogenPowerSource, IElectricMotor {..}
public abstract class Car : Vehicle {..}
public class FordCortina : Car, IInternalCombustionEngine, IPassengerVehicle {..}
public class FormulaOneCar : Car, IInternalCombustionEngine {..}
public abstract class PowerTool {..}
public class ChainSaw : PowerTool, IInternalCombustionEngine {..}
public class DomesticDrill : PowerTool, IElectricMotor {..}
So, I can now state that an object instance of FordCortina is a Vehicle, it's a Car, it's an IInternalCombustionEngine (ok contrived again, but you get the point) and it's also a passenger vehicle. This is a powerful construct.
The poly in polymorphic means more than one. In other words, polymorphism is not relevant unless there is more than one derived function.
In this example, I have two derived functions. One of them is selected based on the mode variable. Notice that the agnostic_function() doesn't know which one was selected. Nevertheless, it calls the correct version of function().
So the point of polymorphism is that most of your code doesn't need to know which derived class is being used. The specific selection of which class to instantiate can be localized to a single point in the code. This makes the code much cleaner and easier to develop and maintain.
#include <iostream>
using namespace std;
class Parent
{
public:
virtual void function() const {};
};
class Derived1 : public Parent
{
void function() const { cout << "derived1"; }
};
class Derived2 : public Parent
{
void function() const { cout << "derived2"; }
};
void agnostic_function( Parent const & bar )
{
bar.function();
}
int main()
{
int mode = 1;
agnostic_function
(
(mode==1)
? static_cast<Parent const &>(Derived1())
: static_cast<Parent const &>(Derived2())
);
}
Polymorphism is One of the principles OOP. With polymorphism you can choose several behavior in runtime. In your sample, you have a implementation of Parent, if you have more implementation, you can choose one by parameters in runtime. polymorphism help for decoupling layers of application. in your sample of third part use this structers then it see Parent interface only and don't know implementation in runtime so third party independ of implementations of Parent interface. You can see Dependency Injection pattern also for better desing.
Just one more point to add. Polymorphism is required to implement run-time plug-ins. It is possible to add functionality to a program at run-time. In C++, the derived classes can be implemented as shared object libraries. The run time system can be programmed to look at a library directory, and if a new shared object appears, it links it in and can start to call it. This can also be done in Python.
Let's say that my School class has a educate() method. This method accepts only people who can learn. They have different styles of learning. Someone grasps, someone just mugs it up, etc.
Now lets say I have boys, girls, dogs, and cats around the School class. If School wants to educate them, I would have to write different methods for the different objects, under School.
Instead, the different people Objects (boys,girls , cats..) implement the Ilearnable interface. Then, the School class does not have to worry about what it has to educate.
School will just have to write a
public void Educate (ILearnable anyone)
method.
I have written cats and dogs because they might want to visit different type of school. As long as it is certain type of school (PetSchool : School) and they can Learn, they can be educated.
So it saves multiple methods that have the same implementation but different input types
The implementation matches the real life scenes and so it's easy for design purposes
We can concentrate on part of the class and ignore everything else.
Extension of the class (e.g. After years of education you come to know, hey, all those people around the School must go through GoGreen program where everyone must plant a tree in the same way. Here if you had a base class of all those people as abstract LivingBeings, we can add a method to call PlantTree and write code in PlantTree. Nobody needs to write code in their Class body as they inherit from the LivingBeings class, and just typecasting them to PlantTree will make sure they can plant trees).

How to exchange data between classes?

I'm learning C++ and moving my project from C to C++. In the process, I stumbled on this problem: how to save/update variables that are in use in several classes? In C I used global variables, but it is not good for C++.
So, let's assume we have 4 classes:
class Main_Window
{
//...
void load_data_menu_selected();
}
class Data
{
//...
double *data;
}
class Load_Data
{
//...
double *get_filename_and_load();
}
class Calculate
{
//...
int do_calculation()
}
So, Main_Window is class for application's main window where it interacts with user input etc.
I want to do:
create an instance of class Data in the Main_Window
use Load_Data for loading data from file and store it in the Data
use Calculation class for doing something with read data in Data class
The question is: where I should create classes, to make Data class members available from other classes. Should I use Inheritance?
Start from observing what are possible relations between instances of two classes. Let us say a is an instance of class A and b is an instance of class B. If a uses b, class A can have as its member instance of class B (b), pointer to b (which is of type B*), or reference of b (which is of type B&). If only one method of class A uses b, you have again same three options: B, B* or B& can be method's arguments. Having B* and B& as class members suggests that a does not control b's lifetime so class A must have a method that sets these members through its parameters. The question of ownership (objects' lifetimes) has a big role in design of relationship between classes. Main relationships are briefly described in this article.
I think you only want to have a Main_Window class, and the rest should be members of that class.
class Main_Window
{
private:
DataObject windowData;
public:
void loadData(string fileName);
void calculate();
}
Inside the loadData and calculate methods, you will be able to access the same data with this->windowData . Sorry if my syntax is bad, my c++ is rusty
Typically, you would pass (const) Data& around as an argument. If do_calculation() needs a Data to work with, then it takes Data&. But I can't really be more specific or useful unless you post more of your design.
You need to know how to design in OO. Thinking in C is different from thinking in c++. You can that your classes have many methods. Well, that sound like a bad design.
I can recommend you to start with the SOLID principle.
Then start writing unit tests for your classes. TDD could help you improve your design even further.
It sounds like you should not use inheritance here. The main reason for saying so is that you have a number of classes (Window, Calculator, etc.) using or doing something to an entity (i.e. Data). Inheritance is used to denote an "is a" relationship (i.e. if A inherits from B, A "is a" B).
In this case, you use composition, which denotes a "has a" relationship. So each class takes a reference to an instance of Data, and acts upon that object.
Who owns the Data object? To share a single Data object, you might want to look into Boost shared_ptr, which allows multiple reference-counting pointers to share an object allocated with "new".