C++ Class Design/ Excluding Base Class members - c++

Assuming I just created a class named Base with 2 or 3 Members, that's about this:
class Base
{
private:
std::string name;
std::string number;
public:
virtual std::string get() const;
virtual void set();
//...
};
And in the next step I want to create a few derived classes form this class. But in some of the derived classes I don't need all members of the Base class.
How can I exclude some members of Base-class in a derived class and keep the others?
For Instance in:
class Derived_One : public Base {
private:
std::string wight;
int A;
public:
//...
};
I want to keep only the first attribute of the Base Class (std::string name) and remove the second attribute which is std::string number. How can I exclude it in the derived class Drive_One?
I am looking for an elegant solution for this change or a widely known Design Pattern which I do not know yet.

If your derived class only needs some of the base class, it is a sign that the base class should be split into two. Either one class derived from the other or two separate classes.
An example of the first case could be something like this:
class Base_One
{
private:
std::string name;
public:
//...
};
class Base_Two : public Base_One
{
private:
std::string number;
public:
//...
};
class Derived_One : public Base_One
{
private:
std::string wight;
int A;
public:
//...
};
class Derived_Two : public Base_Two
...
In the second case (if it does not make sense for Base_Two to derive from Base_One), Base_One and Base_Two would be separate classes and derived classes would derive from one or both of them, i.e. the example above would be modified as follows:
class Base_Two
{
private:
std::string number;
public:
//...
};
...
class Derived_Two : public Base_One, public Base_Two
...

derived classes I don't need all members of the Base class.
Which simply says: This is not a common base class!
Whats to do:
Option 1)
Split base class to several ones and create a linear hierarchy structure.
But this may come to a point, where your design would be to complex, especially if it feels natural to cross call from different members of different classes in the hierarchy.
Option 2)
If your design becomes more complex by simply splitting to linear hierarchy, you should give CRTP a chance.
This enables to inject special functionality into a class hierarchy and keeps the design cleaner. The bad side is, that this may lead to a lot of template instances which waste memory. You have a more maintainable design but you may pay with higher memory consumption.
What is the best for your design can't be answered on the fly from some lines of code. Simply try to understand both options and take a decision. Maybe you will change it later.

Related

How to enforce derived class members on derived classes

How does one enforce a derived class to have member data of a specific derived type.
i.e.,
class Project {
public:
int projdata;
};
class Article: public Project {
};
class Building: public Project {
};
class Emplooyee {
public:
std::vector<Project> projs;
}
class Architect: public Employee {
};
class Writer: public Employee {
};
How do I now enforce that Architect objects only have projects of type Building, while Novelist only have projects of type Article? i.e., I want to have something like
class Architect: public Employee {
public:
std::vector<Building> projs;
};
and
class Novelist: public Employee {
public:
std::vector<Article> projs;
};
I could also store pointers to projects and then store cast them into the correct type. Is there a technique or design pattern to enforce such corresponding inheritance rules on members of derived classes?
A compile time solution is to make the base a template:
template<class Proj>
class Emplooyee {
public:
std::vector<Proj> projs;
}
class Architect: public Employee<Building> {};
class Writer: public Employee<Article> {};
Additionally, you can add a one additional non-template base so that Architect and Writer are part of same hierarchy, but that non-template base cannot deal with the projs member.
If a template not an option, then you must rely on runtime checks. For that, Project must be a polymorphic type, and you must use typeid or dynamic_cast, to enforce the invariant. And you must use indirection to store the Project's in the first place. std::vector<Project> cannot store any Building nor Article objects because it only stores Project objects only
Like you mentioned, you could store polymorphic pointers in the base class:
class Employee {
public:
std::vector<Project*> projs;
}
And use dynamic_cast to downcast them:
dynamic_cast<Building*>(projs[i])->doSomething();
But I wouldn't recommend this approach(unless necessary) since this will require you to manage the memory behind those pointers. (Which of course can be off-loaded to std::unique_ptr for example.)
Unless you require the Employee to be a polymorphic class, far simpler approach would be to use a class template
template <typename T>
class Employee {
public:
std::vector<T> projs;
}
which can be used like so:
class Architect : public Employee<Building> {
};
Architect architect;
architect.projs.push_back(Building());

C++: Are common ancestry and an interface/prototype mutually exclusive features of a C++ class?

In C++, does inheriting a common ancestor and inheriting an interface (and requiring definition of a method in derived classes) require multiple inheritance? Eg. do I have to do the following (instead of merging MyInterface and ParentClass):
class MyInterface;
class ParentClass;
class DerivedClass1;
class DerivedClass2;
class SomeOtherType;
class YetAnotherType;
class MyInterface {
public:
// Must be defined in all derived classes
virtual SomeOtherType my_common_fxn(...) = 0;
...
};
class ParentClass {
private:
// Common ancestor
YetAnotherType _useful_member;
}
class DerivedClass1 : MyInterface, ParentClass {
public:
// Do some things with _useful_member, using approach #1
SomeOtherType my_common_fxn(...);
...
}
class DerivedClass2 : MyInterface, ParentClass {
public:
// Do some things with _useful_member, using approach #2
SomeOtherType my_common_fxn(...);
...
}
void fxn_or_method_using(ParentClass);
Is it possible to (elegantly) merge the functionality of MyInterface and ParentClass into a single class? (I believe that as MyInterface is an ABC I cannot use this type as a parameter to fxn_or_method_using.)
Apologies in advance if this is a duplicate- I've searched but none of the existing C++ questions appeared to line up. Q's and/or A's may have been over my (untrained) head.
There's nothing wrong with your inheritance model.
But in C++ you need a pointer or reference for polymorphism. Your fxn_or_method_using takes its parameter by value. That has several problems. It causes slicing, it prevents polymorphic function calls, and it can't work for an abstract type because you can't create instances of those.
If you change fxn_or_method_using to take its parameter by reference not value, then you can declare it as referring to MyInterface if you wish. All the disadvantages disappear and you get the polymorphic behaviour you want.
No. You can mix virtual and pure virtual and concrete inheritance all from the same class in C++ with no problems.
class baseClass{
public:
blah1(){
//stuff
}
virtual blah2();
virtual blah3() = 0;
};
class derivedClass : baseClass
{
};

How to design the following class inheritance?

I am facing problems about class inheritance design. It is shown in C++ as follows:
There are 2 kinds of classes, we call them Object and Component first.
Class Object uses class Component, but problem occurs with their subclasses.
For simple, there are 6 classes.
class BaseComponent{...};
class ComponentA: public BaseComponent{...};
class ComponentB: public BaseComponent{...};
class BaseObject {
public:
virtual bool doSomething()=0;
void setBaseComponent(BaseComponent*c){_c = c;}
BaseComponent* getBaseComponent() {return _c;}
private:
BaseComponent* _c;
}
class ObjectA : public BaseObject {
public:
bool doSomething(){ /*do someting related to ComponentA*/}
void setComponentA(ComponentA* a) {setBaseComponent(a);}
ComponentA* getComponentA()
{return static_cast<ComponentA*>(getBaseComponent());}
}
class ObjectB : public BaseObject {
public:
bool doSomething(){ /*do someting related to ComponentB*/}
void setComponentB(ComponentB* b) {setBaseComponent(b);}
ComponentB* getComponentB()
{return static_cast<ComponentB*>(getBaseComponent());}
}
Now the problem comes:
If I do like the above code, I have to check always the class relationship.
(for example, I have to check real class in ObjectB::getComponentB() when use static_cast)
If I change the code and use ComponentA directly in ObjectA, I'm abandoning the "Dependency inversion", which makes the code not convenient.
So, could anyone give me some advice?
So any subclass of BaseObject always needs the matching BaseComponent subclass?
Make the setter in BaseObject protected. It claims that you can give any object any component, and that's a promise the subclasses can't uphold if anyone but them has access to that setter.
Even better would be to make the component a constructor argument, if that's at all possible.
The idea of using interfaces instead of concrete classes is that when you use a pointer of the interface you do not have to worry about what is behind.
If you are returning the concrete ComponentA and ComponentB then you lose that.
Then, IMO, you should change these concrete classes to be able to return a pointer of BaseComponent and then you will not need the static_cast.

Need help restructuring and/or refacoring this c++ code concerning inheritance between multiple classes

OK, Not sure on the terminology for what I'm trying to do so edits are very welcome.
I've got code such as this:
class CBaseItemTracker
{
public:
CBaseItemTracker();
void IncrementCount() { ++count; }
protected:
int count;
};
class CDerivedItemTracker : CBaseItemTracker
{
public:
CDerivedItemTracker();
void Print() { printf("something:%d\ncount:%d\n", something, count); }
private:
int something;
};
class CBaseClass
{
public:
BaseClass();
private:
CItemTracker item;
};
class CDerivedClass : CBaseClass
{
public:
CDerivedClass();
CDerivedItemTracker GetDerivedItem();
private:
CDerivedItemTracker derived_item;
};
What I would like to accomplish is that CBaseClass::item and CDerivedClass::derived_item are actually the same object such that:
Code within CBaseClass can update item
Code within CDerivedClass can update derived_item (and therby also update item)
Code external to CDerivedClass can retrieve a CDerivedItemTracker object that includes the item variable.
I feel like I am trying to do something that is fundamentally wrong but I'm not seeing a good way to resolve it.
Your goal is that code within CBaseClass can update base member item and
code within CDerivedClass can update members derived_item as well as item.
Is it a member access problem ?
The first two constraints are the basics of inhertance.
The only problem in your code is that you have item member as private. This means that the derived classes won't have access to it. Just change it to be protected instead:
class CBaseClass
{
public:
BaseClass();
protected: //<===== derived classes will have direct acess to this member
CItemTracker item;
};
class CDerivedClass : CBaseClass
{
public:
CDerivedClass();
CDerivedItemTracker GetDerivedItem();
private: // you can leave it private, but if further dirved classe need access
// make it protected as well, but then you should consider public inheritance
// so that the further derived also see the item.
CDerivedItemTracker derived_item;
};
Now the derived class sees both itmes. In GetDerivedItem() you can choose which item to return. But item and derived_item will remain unrelated, as your class definitions define two distinct members.
Or is it about sharing a single (derived) item ?
The third requirement makes the things a little bit more complex. I'm not 100% sure of your intentions. But if the intention is to extend in a derived class an item of the base class, this wont be possible as such, due to C++ standard constraints on the object layout.
Fortunately there are two main alternatives: templates or dynamic member.
Template approach
The template approach should be considered if at compile time you do already make the choice of the member type.
template <class myitem>
class CBase
{
public:
CBase() {}
protected:
myitem item;
};
template <class myitem>
class CDerived : CBase<myitem>
{
public:
CDerived() {}
myitem GetDerivedItem() { return item; }
};
You can use this as follows:
CBase<CBaseItem> b;
CDerived<CDerivedItem> d;
d.GetDerivedItem().Print();
The principle is that for object d in CBase would have a CDerivedItem item, even if you would only access to the subset of its public CBaseItem members.
Dynamic approach
The dynamic approach doesn't use templates, but creates the item during the construction.
Here I present a simple implementation based on references, taking the luxury of some unused members. A more space efficient pointer based variant with dynamic allocation of the item should be prefered whenever space is critical.
class CBase
{
public:
CBase() : item(base_item) {} // when lonesome object: uses its own item
protected:
CBase(CBaseItem &itm) : item(itm) {} // when subovject of a derived class
CBaseItem &item;
private:
CBaseItem base_item; // used only for non derived CBase object.
};
class CDerived : CBase
{
public:
CDerived() : CBase(derived_item) {} // Tell the base class that there's already an item to be used.
CDerivedItem GetDerivedItem() { return derived_item; }
// we can use item as well: it'll be the CBaseItem subobject of derived_item
private:
CDerivedItem derived_item;
};
ATTENTION: for this to work you need public inhertance between item classes ( class CDerivedItem : public CBaseItem)
The difficulty here, is that base classes are constructed first. So you have to provide to the base class constructor the item reference that it has to use. If inadvertently you'd forget, the base would think it is a free object and will use a separate item. THis is why I'd suggest to use the template approach if possible.

C++03: Add fields to several derived classes

I have several derived classes (e.g. DerivedX, where x is derived class number) that differ in fields and member functions.
Than I want to extend each derived class with some set of properties (can be organised as a field Extension ex), preserving each DerivedX class. The latter means, that we could create "clear" DerivedX objects that would not contain the property Extension ex.
The derived objects are created in some code place (e.g., in function main()), than, if they possess an extended functionality, this functionality should be used (get,set, other methods are called from main()).
The first idea was to add this new property to every derived class forming new class (ExtendedX) for each of derived classes. But I feel the code would become bulky, it seems, this approach is bad:
class Base
{
protected:
int b;
...
}
class Derived1: public Base
{
protected:
int d1;
...
};
class Derived2: public Base
{
protected:
int d2;
...
}
...X classes defined
class Extended1: public Derived1
{
protected:
Extension ex;
public:
int getExProperty1(){return ex.getProperty1();} // the realization could differ: we could also return copy of Extension object, pointer, set every field separately or the whole Extension object
}
class Extended2: public Derived2
{
protected:
Extension ex;
public:
int getExProperty1(){return ex.getProperty1();} // the realization could differ: we could also return copy of Extension object, pointer, set every field separately or the whole Extension object
}
...X classes defined
The demanded functionality is repeated in each class in that case. It's highly deprecated practice.
The other (second) idea was to declare "class Extension" that would contain the property considered ("Extension ex" in the example) and create its objects on-demand along with the objects of classes DerivedX, when we need DerivedX objects to possess this property.
The third idea was to include pointer to Extension as a field to the Base class and simply initialize it to NULL when we don't want to use the extended functionality. But then, how can we call methods of Extension class from main()?
Extended functionality could also be different in the future (derived classes are extended in accordance with the kind of problem being solved), that's why the second and the third ideas are also better, than the first.
Is there any good solution to add pack of properties and functionality to multiple derived classes?
EDIT1:
I tried to implement mixin through CRTP, as suggested by Deduplicator.
However, the code fails with:
«class Base» has no member named «getProperty1»
«class Base» has no member named «setProperty1»
The code:
#include <iostream>
using namespace std;
class Base {
int a;
public:
virtual ~Base(){}
};
class Derived1: public Base
{
public:
virtual ~Derived1(){}
};
template <class T> class Extension: public T
{
int prop1;
public:
void setProperty1(int _p){prop1=_p;}
int getProperty1(){return prop1;}
};
int main()
{
Base* der = new Derived1();
Base* e = new Extension<Derived1>();
e->setProperty1(10);
cout<< e->getProperty1();
delete der;
delete e;
return 0;
}
Changing
e->
to
static_cast<Extension<Derived1> *>(e)->
makes the code working.
How to use Extension class objects right in this case?
Use the CRTP:
// Classes implementing additions
template<class T> class Extended : public T /*, potentially additional bases */ {
// Common extension here.
}
Another option, if you can redefine the various Derived classes but can't change the definition of Base, is to shove Extension into the class hierarchy between them and Base:
class Base
{ // ...
};
class Extension: public Base
{ // ...
};
class Derived1: public Extension
{ // ...
};
class Derived2: public Extension
{ // ...
};
This way, anything that doesn't need the new APIs in Extension can continue to use Base*, and the parts that need the new API can use Extension* (or dynamic_cast<Extension>(baseptr)) instead.
This assumes Extension needs access to Base. If it doesn't, then you can just implement Extension as a mixin:
class Base
{ // ...
};
class Extension
{ // ...
};
class Derived1: public Base, Extension
{ // ...
};
class Derived2: public Base, Extension
{ // ...
};
Composition or inheritance ?
when we need Derived objects to possess this property.
This sounds as if an object and its extended property have a "has-a" and not and "is-a" relationship. This would suggest composition rather than inheritance as solution.
"on demand" , "if we don't want" ...
These suggest an optional relationship. It sounds as if you'd decide at runtime and for each object if the extension is needed or not. This reinforces the preference for composition over inheritance.
To achieve this kind of behaviour with inheritance needs polymorphism, and you'd have to use pointers/references everytime you need to work with an object.
Extended functionality could also be different in the future (derived
classes are extended in accordance with the kind of problem being
solved),
In the future, could there be further derivation for the derived ? If yes, how would this further derivation relate to the extension ? If you'd say that further derivation would be independent of the extension, then composition should definitively be the choice.
Now which one of 2 and 3 to prefer ?
Looking at all the arguments above, the third option could be very interesting for both your current needs for a common extension, but also future needs.
Here is the general idea:
class Base {
...
protected:
Extension *ex;
void setExtension(Extension *e); // to be called by ctor or the derived.
public:
bool isExtended() { return ex!=nullptr; }
int getExProperty1(){ if (isExtend()) return ex->getProperty1();} // common member functions
};
But for this to remain extensible for future evolutions, Extension should define its member functions virtual. Then later some derived class could use a derivation of Extension:
class MyDerivedExtension : public Extension { // specially for Derived1 extensions
protected:
string myspecificproperty; // specific for Derived1
public:
int getPropery1 () { /* calculate it differently than for basic Extension */ }
string getProperty2 () { /*...*/ } // specific to Derived1
};
class Derived1: public Base
{
...
protected:
void setExtension(MyDerivedExtension *e) { Base::setExtension(e); } // to be called by ctor.
public:
string getExProperty2(){ if (isExtend()) return ex->getProperty2();} // non common member
};