It seems to me that my class is too big and complicated, I would like to reduce it. Can I use inheritance in this way, given that I created the InitCar class only to inherit it and am not going to use objects of this class explicitly.
Before refactoring. People and License are not my own classes, I cannot change them.
class Car
{
public:
void Move();
void SpeedUp();
void SpeedDw();
//More other
private:
int speed = 0;
std::string name;
int id = 0;
People owner; // not my own class
License license; // not my own class
void InitCarFromConfig()
{
//Here I read the data from the file
}
void InitOwner()
{
//Here I init the People owner
}
void InitInspection()3
{
//Here I init the License license
}
};
After refactoring
class InitCar
{
protected:
std::string name;
int id = 0;
People owner; // not my own class
License license; // not my own class
void InitCarFromConfig()
{
//Here I read the data from the file
}
void InitOwner()
{
//Here I init the People owner
}
void InitInspection()
{
//Here I init the License license
}
};
class Car : InitCar
{
public:
void Move()
{
InitOwner();
}
void SpeedUp();
void SpeedDw();
//More other
private:
int speed = 0;
};
Is this use of inheritance acceptable and are performance issues possible?
Although it is true that you can use inheritance to reduce the size of you classes and reduce code duplication for other classes (which can also inherit InitCar for similar base functionality), it is actually not a good idea.
Functionality-wise, it does work, it does reduce code duplication and class sizes. However, it is a bad design, because it uses inheritance wrong, and breaks concepts of "clean code".
When you create a class, you create an entity which represents something. Inheritance create relations between those entities. Saying that Car inherits InitCar is saying that Car is a sort of InitCar, which logically makes no sense, because InitCar is just a helper class.
You can solve this if the base type was an actual entity, like Vehicle, and you had multiple vehicles. However, your InitClass is specifically intended to split you code, so it doesn't actually make a Vehicle, renaming it won't fix the design.
Composition over inheritance
A well known concept in "clean code", saying that it is better to hold functionality helping classes as variables in the class, rather then inherit from a base class. It is both more flexible for switching implementations, and does not abuse the purpose of inheritance:
class Car {
public:
void Move();
void SpeedUp();
void SpeedDw();
//More other
private:
int speed = 0;
std::string name;
int id = 0;
People owner;
License license;
HelperClass helper; // new class for initing..
void InitCarFromConfig()
{
//data = helper.InitCarFromConfig();
}
void InitOwner()
{
//owner = helper.InitOwnerForCar(param);
}
void InitInspection()
{
//data = helper.InitInspection(param);
}
};
Now we simply delegate our calls to the helper class (whose name is just a stub, you should have a name matching what it does, or maybe several classes). So we do save some space, we don't abuse inheritance and typing, and we now actually have flexibility in implementation, since now we can replace the instance of helper and get a new logic.
How do we init helper? Usually receiving via the constructor is the best idea. But you can create inside the class if you really want to.
Best design for your case
But is it the best design here?! No actually. Because the real problem in the class is the existence of the Init_ methods within the class.
When creating a class, it is important that when the constructor finishes running, the class is completely initialized. When it is not, we create several problems:
Risk a chance that the class is used, and some properties/methods are not complete for use, causing errors
Complexity of the class is increased, making maintenance harder (which is what you pointed as the issue for you).
Limits the users of the class from flexibility in its creation, thus limiting the design options for using the class. Creating tests for example, will be a nightmare.
Very risk for multithreading use, and harder to handle
Instead than, what we can do is receive all the data we need to operate from the constructor, and simply store it:
public:
Car(std::string name, id, People owner, License license);
Now comes another issue: what if it is difficult to perform initialization. After all you have 3 methods for initializing your class, so could be not easy for users. This is were the Factory design pattern comes in. We will create a class, named CarFactory (or so) and use it to create our classes. Within it, it will have all the logic to init the class data:
class CarFactory {
public:
Car* CreateCar(params_from_user) {
// init data
return new Car(data);
}
};
What did we accomplish with this:
We made Car smaller and less complex
We allowed users more options about how to use Car
We maintained the Init option from earlier, to help create Car
Our code is a lot easier to look at and maintain because it is separated logically, and classes are small
Car is fully initialized after constructor call
Related
Let say I have some data structure in a class as follow
class DataStructure
{
DataStructure();
~DataStructure();
void reset();
void init();
void setiX();
...;
int getiX();
double get dx();
void addToList(OtherDataStructure dt);
private:
int ix;
int iy;
int iz;
double dx;
...;
vector<OtherDataStructure> dtStVec;
};
so I usually have this class used as the following way
class manageSomething
{
manageSomething();
~manageSomething();
func1();
func2();
...;
funcN();
private:
some vatiables;
DataStructure structure; //HERE
};
so I usually have to use getters and setters to access the data structure variables
is it better inherit the data structure, and access all element directly, if the inheriting class is not in the main application, as follow
class manageSomething : public DataStructure
{
manageSomething();
~manageSomething();
func1();
func2();
...;
funcN();
private:
some vatiables;
};
so the usage of manageSomething is used as
int main()
{
manageSomething manager;
///manager.stuff ....
return EXIT_SUCCESS;
}
and when do we decide which one to choose from?
You should not inherit publicly unless the class that you are writing indeed extends the class from which you are inheriting, i.e. manageSomething is a kind of DataStructure. This is known as Liskov substitution principle. Violating it leads to serious readability and maintainability issues in your code.
The rules are less strict with private inheritance, but in general you should prefer composition to private inheritance, except under very specific circumstances.
The upshot of this is that your first code snippet (with the composition) does everything right, you do not need to change it.
That's really depend on the case !
If you have more than 1 DataStructure in your manager, you need to have a manager with a STL containers of DataStructure.
If you have only ONE DataStructure in your manager, your manager is probably useless et you can use directly a DataStructure.
BUT if you think that it is needed cause you call function which haven't their in DataStructure you can inherit of DataStructure.
I need to have more precision of what you do with you DataStructure for a better answer please.
First,
class manageSomething
{
manageSomething();
~manageSomething();
func1();
func2();
...;
funcN();
private:
some vatiables;
DataStructure structure; //HERE
};
This is part of your code, I want to tell you, that all your class is private. C++ makes everything private as a default.
Going back to your question. In most cases best way is getters and setters. Never use public varables. There is difficult to tell if inheritance is the best option, sometimes it is, but not often.
There is one good but not perfect rule for inheritance. You need to determine if object has some other object or is that object.
class Engine
{
...
};
class Car
{
private:
Engine m_engine;
...
};
class BMW : protected Car
{
...
};
In this example BMW is car, so it is better to use inheritance, however car has engine, so we put this object inside this class.
What is more about inheritance, it is better usually inherit in protected way. You can use public inheritance if you want to inherit that class.
Let's say we use public inheritance for this:
class BMW : public Car
{
...
};
class X7 : protected Car
{
...
};
I hope it helped a little.
Consider an abstract class called Vehicle. This vehicle has following abstract operations
- Start
- Break
- Accelerate
class Vehicle
{
public:
virtual void Start() = 0;
virtual void Break() = 0;
virtual void Accelerate() = 0;
};
Now consider that we have a special kind of vehicle derived from Vehicle class namely VehicleA.
Class VehicleA: public Vehicle
{
private:
double speed;
double temperature;
int id;
double miles;
public:
void Start();
void Break();
void Accelerate();
void horn();
};
If I now have a vehicle which is almost similar to VehicleA type but slightly differs in say the type of engine or some other characteristics like color, which is the best way to accommodate such a small change in the class hierarchy design. Should I
define another class VehicleB derived from Vehicle class ? or
define another class VehicleB derived from VehicleA ? or
something else ?
Thanks
In this case, you really should consider composition over inheritance.
Depending on what the class Vehicle actually means to you (and be careful with that, intuition isn't necessarily your best friend when going through this kind of class design : think about the famous Square/Rectangle case), you could have your VehicleA declared the following way (don't forget the virtual keyword):
class VehicleA: public Vehicle
{
private:
//Your specific private
Engine* m_engine;
Color* m_color;
//Add any "modifiable" part as long as it fits
public:
virtual void Start();
virtual void Break();
virtual void Accelerate();
void horn();
};
with Engine and Color two classes (that can be abstract or not) that hold the details you want to implement.
You add another level of abstraction : your VehicleA has an engine (with its own interface), but don't care about its details (as long as the engine has an interface the vehicle can interact with), and makes it possible to add easily a new type of engine.
As a general rule when designing a hierarchy, if you think you must implement a new derived class of a specific class, ask yourself the following :
Is this class a more specific version of its parent class ?
In your case, it feels like a VehicleB wouldn't be a more specific version of a VehicleA though that's still a matter of opinion, as it completely depends on what you want to do. In this case, it feels like the way to go should be composition.
What you have here is a problem related to "Separation of Concerns". The "Vehicle" concept has a few basic operations some of which you identify, for example "Accelerate". Now the implementation of "Accelerate" is dependent on certain parameters, such as maximum torque, brake-horsepower etc...
These should should be encapsulated outside of the vehicle... but why? Well because they the Vehicle represents a concept, not an implementation. Accelerating will use an engine in the same manner, no matter what that type of car involved. let me use a real-world example:
A McClaren F1 is a Vehicle, in fact it is a car, which contains an engine, has a chassis, has some tyres and suspension etc...
A Volkswagon Golf GTI is a Vehicle, in fact it is a car, which contains an engine, has a chassis, has some tyres and suspension etc...
The user will drive one car in the exact same manner as another car, even if it has hugely different sets of component parts. The user does not need to even be aware of most of the details. This is why you need to separate out your Vehicle concept from the implementation details that are encapsulated by the specific components of your Vehicle.
You should do the same for your "Brakes" as well, and you should inject the Engine and Brakes into the Vehicle at construction (look up Dependency Injection).
Now for colour: I would recommend that you place this at the top level of your class hierarchy, in the Vehicle abstract class. It is something that applies to all classes of vehicles, and is used in the same way by all, and does not affect any implementation. It should be set via the constructor probably, with a repaint function offered for changing it (once the necessary fees are passed to the Garage via the SalesPoint of course!).
So the class in the end might look like this...
class Vehicle
{
private:
std::unique_ptr<Engine> engine;
std::unique_ptr<Brake> brakes; // same for "Suspension", "Chassis" etc...
VehicleColour colour; // An enum defined here or elsewhere.
public:
Vehicle( std::unique_ptr<Engine> engine, std::unique_ptr<Brake> brakes, VehicleColour colour)
: this->engine(std::move(engine)),
this->brakes(std::move(brakes)),
this->colour(colour) {
}
virtual void Start(const Key& key) {
engine->ignition( key );
brakes->disengage();
}
virtual void Break( BreakPattern pattern ) {
engine->setThrottlePosition( NO_THROTTLE );
brakes->engage( pattern ); // e.g. SIMPLE_HARMONIC, or SLAM... brakes may have ABS or not but you don't need to know
}
virtual void Accelerate() {
brakes->disengage();
engine->setThrottlePosition( TO_THE_METAL );
}
};
Using it:
std::unique_ptr<Brake> absBrakes( new VwAbsDiskBrakes() );
std::unique_ptr<Engine> fastEngine( new TurboV8( FOUR_LITRE ) );
Vehicle hotrod( absBrakes, fastEngine, RED );
hotrod.start();
hotrod.accelerate();
It uses the components via their interfaces, so it doesn't need to know specifics. The sub-classes of Vehicle then do not need to worry about anything that is not Vehicle specific. You will only need a subclass of Vehicle if there is a vehicle that does not fit your generic concept a vehicle (for example if there is a vehicle out there with no brakes).
How to handle classes that are slightly different?
This depends completely on what you are trying to solve. The Vehicle class isn't a real car, it is a model based on information of the real world, needed to make a working program. It is not one set of fixed rules.
About the color: this has nothing to do with the behavior of the class, so if possible ignore it, if not, make an extra field.
About the type of engine: does this make a noticeable difference to the behavior or is it just a matter of setting some parameters (power, couple, fuel consumption)? In case of the engine, there is a good chance that you can have a hierarchy of engines that can be contained in the vehical.
I am currently redesigning a C++ project, and wanted some opinions on how variables should be handled when classes with a "has a" (composition) relationship need to access variables that arguably belong to the parent, for example:
A computer object has a network card object. The computer object has an owner variable. For example
class Computer {
string get_owner(); // getter as an option?
private:
std::string owner = "baylesj";
NetworkCard nic;
}
class NetworkCard {
public:
NetworkCard(Computer *parent);
send_packet();
broadcast_owner(send_packet(m_parent->owner)); // this is kind of ugly
private:
Computer *m_parent;
}
Let's say I have a function in network card that needs the owner. Is it better to pass the owner in as a member variable of network card when I initialize in in Computer, or should I have a parent pointer in NetworkCard that can access the member variable of Computer, a Getter/Setter, or some other relationship? I know it's fairly common practice to have a pointer to parent in the child, but is it a good idea / proper OOP?
**The computer thing is just for example, IRL it's something else so don't get too hung up over it :).
I see you recognize that it is desirable to minimize unnecessary coupling. To do so you can design the NetworkCard class to be unaware of the implementation details of the parent. Here is one approach that passes the name to broadcast at network construction:
class Computer {
public:
Computer(std::string const &owner) : m_Owner(owner), nic(owner)
{
}
private:
std::string m_Owner;
NetworkCard nic;
};
class NetworkCard {
public:
NetworkCard(std::string const &owner)
{
broadcast_owner(owner);
}
send_packet();
broadcast_owner(std::string const &owner);
private:
};
If you find there are too many such variables to pass as constructor parameters (I like no more than two or three), then you might discover that composition is the wrong tool for the problem. Often the number of parameters is small unless it is actually an "is-a" relationship, in which case inheritance might be a better tool.
Good day to you all...
I'm working on a complex project on my company which I use some wringled Factory Design pattern in the project. Omiting the details; I have some classes (I call them "Devices") which can only be created by "Readers":
class DeviceBase // this is a virtual base class
{
public:
//some stuff
friend class ReaderBase; // this is OK and necessary I guess?
private:
DeviceBase(); // cannot create a device directly
//some more stuff
}
class Device1: public DeviceBase // some extended device
{
public:
//some stuff
private:
//some more stuff
}
class Device2: public DeviceBase // some other extended device
{
public:
//some stuff
private:
//some more stuff
}
Now the "Reader", which happens to be factory for devices:
class ReaderBase
{
private:
DeviceBase[] _devices; // to keep track of devices currently "latched"
public:
// some other methods, getters-setters etc ...
// this method will create the "Devices" :
virtual bool PollforDevice ( DeviceType, timeout) = 0;
}
Now, this is my factory class; but it's (as you can see) pure virtual. I have special Readers inherit from this one:
class InternalReader: public ReaderBase
{
public:
// define other inherited methods by specifics of this reader
bool PollforDevice( DeviceType dt, timeout ms)
{
switch(dt)
{
case Device1: { /* create new device1 and attach to this reader */ } break;
case Device2: { /* create new device2 and attach to this reader */ } break;
}
// show goes on and on...
}
}
class ExternalReader: public Reader
{
public:
// define other inherited methods by specifics of this reader
bool PollforDevice( DeviceType dt, timeout ms)
{
switch(dt)
{
case Device1: { /* create new device1 and attach to this reader */ } break;
case Device2: { /* create new device2 and attach to this reader */ } break;
}
// show goes on and on...
}
}
The reason I use this pattern is: I'm writing for a system that can have multiple of these "readers" attached at the same time and I must use them all at the same time.
And these "Devices": I can make theirs constructor public too, and everyone would be happy; but I want to make sure that they are not created by the code writers themselves (to make sure other coders of it)
Now the questions:
Should I explicitly declare in every "Device" that ReaderBase is a friend? Or just declaring at the base "DeviceBase" should be enough?
Should I explicitly put in every "Device" that the "Readers" inherited from the "ReaderBase" are also friends of these devices, or just putting ReaderBase is enough?
Instead of making whole "ReaderBase" class a friend, can I (and should I) just make the member method "PollforDevice" a friend? Knowing that it's a pure virtual method, would that make inherited copies friends as well?
I'm sorry that the question is a very long one, but I just want to make it clear.
Thanks in advance...
Why bother about constructability of pure abstract base classes like DeviceBase? It can't be constructed anyway if it is a properly designed contract or abstract base class. Unless you have to fit into some kind of framework which you didn't mention, just do the opposite of hiding, e.g.:
struct DeviceBase {
virtual void Foo() = 0;
virtual void Bar() = 0;
virtual ~DeviceBase() = default;
};
By the way, declaring the constructors or destructors private will very effectively make your class "sealed". If for some reason DeviceBase is not abstract (which were a serious design flaw in my eyes) make constructors protected not private. Where you need to bother, is the constructor accessibility of the concrete Device classes. Assuming that you are going to "publish" these implementation classes (i.e. their definitions are accessible to users of your library) and you wish to stress that direct construction is prohibited, use the "access idiom" (my invented name for this):
namespace impl_detail {
class DeviceAccess;
}
class ConcreteDevice1 : public DeviceBase {
friend class impl_detail::DeviceAccess;
// implementation of DeviceBase and all other stuff go
// into the "private" section
};
namespace impl_detail {
class DeviceAccess {
template< class TDevice >
static DeviceBase* Create()
{
return new TDevice;
}
};
};
In your Reader classes use impl_detail::DeviceAccess::Create to construct Device instances, e.g.:
// Your ExternalReader::PollForDevice...
switch (dt) {
case Device1:
return impl_detail::DeviceAccess::Create<ConcreteDevice1>();
case Device2:
// etc...
}
Long story short, best solution is to not publish concrete implementation classes at all, second best some kind of "psychological barrier" which restricts construction, e.g. of the above kind...
Should I explicitly declare in every "Device" that ReaderBase is a friend? Or just declaring at the base "DeviceBase" should be enough?
Should I explicitly put in every "Device" that the "Readers" inherited from the "ReaderBase" are also friends of these devices, or just putting ReaderBase is enough?
As friendship is not inherited (at either side of the friendship relation), the only way your scheme will work is when you declare friendship of every derived Reader in every derived Device. This creates a tight coupling between the Reader classes and the Device classes that is not a nice design.
3) Instead of making whole "ReaderBase" class a friend, can I (and should I) just make the member method "PollforDevice" a friend? Knowing that it's a pure virtual method, would that make inherited copies friends as well?
You could make ReaderX::PollforDevice a friend instead of the entire ReaderX class, but it won't help you much and only opens the door for hard to resolve circular dependencies.
Actually, it is quite hard to create a design where classes of hierarchy X can only be created by classes of hierarchy Y and no one else, without creating a tight coupling between the classes in both hierarchies.
My approach would be
First and foremost, educate your coworkers that if they want a DeviceX, then they can obtain it from a ReaderY and in no other way. Make sure this is enforced in code reviews.
All the other steps are just damage control.
Make sure only the BaseDevice class gets exposed to code outside the Reader's implementation.
Make the destructor of all Device classes protected. This ensures that Device classes can only be cleaned up by derived classes or friends (and automatically rules out stack allocation by non-friends). Should get someone to think twice if they accidentally try to use a Device class directly.
Make the ReaderBase a friend of DeviceBase and give ReaderBase a function to do the actual cleanup of a Device. This is needed to ensure Devices can be cleaned up.
I have some problem with organizing classes properly.
Suppose, I have some class ABase. When I want to create some different (more particular) abstraction of this class (denote it AParticular), I can use inheritance or just composition. Then it is easy to treat AParticular as ABase: in case of inheritance it is made automatically, in case of composition I can create some const ABase& AParticular::GetABasePart() method. By this I avoid code duplication and get polymorphic features.
But, when I have two or more classes that interact with each other, I have some problems to create analogues of these classes in a more particular abstraction.
For example, suppose, I have two classes Car and Station. Station has some public methods to maintain cars:
class Car {
...
}
class Station {
...
void AddCarToPlaceNumberN(const Car& car, int place_number) {
// adds car to some_container<Car>.
}
Car* GetMutableCarPointer(int place_number) {
// gets mutable pointer from some_container<Car>.
}
...
some_container<Car> cars;
}
Now, I want to create Truck and TruckStation classes: they are pretty similar to Car and Station classes and have minor changes. To understand problem it is sufficient to think as they do absolutely the same as Car and Station classes, but their methods have a bit other name (i.e. TruckStation::AddTruckToPlaceNumberN instead of Station::AddCarToPlaceNumberN)
How to organize the code of new classes to provide these features?
No code duplication, I want to use the already created Car and Station class methods.
Fast conversion Truck& -> Car&, TruckStation& -> Station& (Not necessary inheritance, composition is suitable also), since I want sometimes to treat Truck as Car and TruckStation as Station.
All interaction methods in level Car-Station should be realized in a new level Truck-TruckStation.
The main problem is the 3d item. Let's consider two interaction methods:
1) It is ok with this method:
// If we use inheritance in creating Truck and TruckStation, then we just run
void TruckStation::AddTruckToPlaceNumberN(const Truck& car, int place_number) {
AddCarToPlaceNumberN(car, place_number)
}
// If we use composition, then it is appropriate to run sth like that:
void TruckStation::AddTruckToPlaceNumberN(const Truck& car, int place_number) {
station_.AddCarToPlaceNumberN(car.GetCarPart(), place_number);
}
2) But I don't know how to implement the analogue of Station::GetMutableCarPointer():
// For example, if TruckStation was inherited from Station, then suppose:
Truck* TruckStation::GetMutableTruckPointer() {
Car* car = GetMutableCarPointer();
// Ups! I need to return Truck*, not Car*.
}
Repeat the question: how can I implement these classes to provide:
no code duplication.
Possibility to treat new classes as their higher level abstractions.
Implementation methods such as TruckStation::GetMutableTruckPointer() that correspond to Station::GetMutableCarPointer().
Tnx!
Getting specific to your code. I would do it this way.
Base class Vehicle extended by specific classes for Car and Truck.
Class Station with methods
void Station::AddVehicleToPlaceNumberN(const Vehicle& vehicle, int placeNumber)
Vehicle* Station::GetMutableVehiclePointer()
Reasons behind the design/class organization.
1. Use inheritance only when there is a need of different implementations. If different implementations of an inherited method do the same thing (like in case of AddVehicleToPlaceNumberN) then there is no need for separating the implementations.
2. Use of generic method name always helps in simplifying the code. The methods can be overloaded (passed with different number and type of parameters) to get a specific thing done.
The lazy way is to make the station use a generic type T so that; (Bear with me, I'm not completely clear with the C++ inheritance syntax, but the principle applies)
template<typename T>
class Station<T>:CarStation
{
void Station<T>::StatAddCarToPlaceNumberN(const T& car, int place_number)
{
// adds car to some_container<T>.
}
T * Station<T>::GetMutableCarPointer(int place_number)
{
// gets mutable pointer from some_container<Car>.
return dynamic_cast<T>(car);
}
}
And have an abstract superclass Station that implements a function to return a base pointer, say
class CarStation
{
//...
some_container<Car> cars;
virtual Car * CarStation::GetMutableCarBasePointer(int place_number) = 0;
}
Car * CarStation::GetMutableCarBasePointer(int place_number)
{
//gets mutable pointer to base class from some_container<T>
}
Now, if you want, you can create a new class TruckStation (This I am uncertain of in C++, again, I call principle)
class TruckStation : Station<Truck>
{
//...
}
or just go with Station<Truck>