c++ base class object to call unknown methods in subclasses - c++

I am facing this problem:
An upstream application defines a class (e.g. box), and a member (say property) with a base class type. I would make a derived class for that member, add new members and methods without updating their application.
Essentially I do box->property = make_shared<myProperty>(). Is there a way to keep the interface of calling the members and methods the same? That is, to access a property using box->property->length or box->property->GetWeight(), rather than dynamic_pointer_cast<myProperty>(box->property)->GetWeight(). The challenge here is they won't update the base property class, and I am not supposed to change box. But we wish to keep the interface the same so our customers won't complain.
Is it possible? If not, how could we do to best keep the main app and my plugin relatively independent while minimize the changes on the customer side? Any suggestions are welcome.

Looks to me like the derived class for that member property violates Liskov's substitution principle.
You mentioned not being able to modify the Box class.
But are you allowed to modify the property base class? I suggest you add your "additional" methods of your derived class to the property base class.
The intent here being that the interface between the base and derived class should be one and the same. So do this only if it makes sense design wise.

Related

Variable types from inherited classes

If I have a class that inherits from a base class, can I use that base class as a variable type in c++?
class Component {
// Code here
};
class TransformComponent : public Component {
// Code here
};
class Entity {
// Code here
Component *getComponent(Component *searchComponent) {
// Code Here
}
};
as you can see here, I am using the base class "Component" as a return type and a variable type. The problem is that the user may input a "TransformComponent". The only reason I am asking this is because the "TransformComponent" class inherits from the "Component" class and there might be a way to do this?
<Entity>.getComponent(Component &TransformComponent());
The answer I'm looking for is one that works both for the return type, and the variable type.
Absolutely! It's one of the beauties of OOP. Your instanced class of type TransformComponent is both an instance of Component as well as TransformComponent.
If you had some function that returned a type of Component, this could return any class derived from Component as a Component! If you later wanted to refer to it as its sub-class, you might have to check its type and then cast to it, but what you want is absolutely possible, and you're going the right way about it.
In fact, in the example you describe, were you are using Component and the user might pass a TransformComponent, all of the base methods and properties that the Component possesses will be possessed by TransformComponent too. It will look and feel as if it was a Component, with all the benefits of being one.
The only time a problem will arise is if you specifically want to access the features of a TransformComponent, and the user passed a Component. The parent class doesn't know about the sub-class stuff, because it isn't an instance of one, it will throw up errors for you. Sub-classes build upon the base class, so they have all the base-class stuff, plus more. Basically its only an issue when your example is reversed.
Your Entity.getComponent() method suggests that it only cares that the provided argument is a Component ... not any specialization, such as TransformComponent, of that original class.
So, if you find yourself writing logic that actually cares that "this Component might actually be a TransformComponent," then "warning bells should be going off." Create method definitions within the class that are as specific as possible.

What benefit I will get to create an abstract class rather than the base class in CPP?

In our project - C++, we have the generic module called "ContentCache". From this contentcache, we have derived the customer specific contentcache - for example - Airtel, TataSky. For example, the base contentCache has the method - create the database table, store the basic information. The other types of contentcache which has a relationship like airtel content cache is a type of contentcache. This airtel content cache is customized - overriden a few methods. However, the rest of it are the same. On a few products, we simply use the generic - contentCache. My question is do we need an abstract class - ContentCache - IcontentCache. Also, what is the good way - creating an abstract class or just create a generic base class. What advantage do we get with the IContentCache- i.e. abstract class. I am looking an answer from the design pattern point of view. Also, the programming point of view.
usually you use an abstract class if you define some functionality which can only be used if some additional, unavailable information (or functionality), is needed for that class to work. The unavailable but required information is defined as abstract methods of the class, then derived classes provide that extra information (or functionality).
In your example, if you can usefully have a generic ContentCache then it doesn't need to be abstract. But you might have a design where a ContentCache cannot be instantiated without knowing the name of the specific customer. In this case you might define all of the cache functionality in the abstract base class and have an abstract method which provides the name of the customer. Then in the derived classes you provide the implementation which returns that customer name and the class then has everything it needs to create the cache.
Admittedly this is not a great example as you could just provide the customer name in the constructor of the class, but you mention that in the derived classes you 'override a few methods'. These methods might be candidates for being abstract if they provide functionality which cannot be determined without knowing the customer.
Abstract class is better than just a normal base class. From the design perspective when ever we design a base class , we know that there is going to be inheritance (virtual functions). So we try to collect the common functions in the base class which will mostly be over ride in the derived class. Abstract means hiding the actual implementations from the outside world.Our implementations are our wealth.So base class needs to only work as an interface kind of thing and it should not have any implementation.
Abstract classes are good for you when ever your derived classes are going to ALWAYS use their derived class function definition rathar than using the base class definition.
Normal base classes will be useful , if you are going to use the base class virtual function definition along with the derived class function definition. Normal base class it will be good for small inheritance levels.

Testing STI base class in isolation with Fabricator

I am using STI in my current project and would like to be able to test the base class in isolation. Unfortunately, when I try to create an instance of the base class the fake value being inserted into the type column causes an error.
Invalid single-table inheritance type: fakevalue is not a subclass of
MyTable
Since I could potentially have an unlimited number of subclasses, I would like to be able to test my base class in complete isolation from the subclasses. Since Rails is checking for the subclass this appears to be impossible.
Is there a way?
So after discussing with a coworker, we came to the following solution.
In the spec file, I added an empty dummy class and inherited from my base class. I can then test using this dummy class. Since the dummy class is empty the only logic that gets tested is the base class. I can then add/remove subclasses without fear of breaking the base class tests.

What is special about the abstract class mechanism in C++?

I have question that bothers me for few days.
Abstract class is a special type of class that we cannot instantiate, right?. (Which is denoted/specified by giving a "= 0" to at least one method declaration, which looks like an afterthought).
What are the extra benefits that the abstract class mechanism brings to C++, that a 'normal' base class cannot achieve?
According to the wikibooks section on abstract classes:
It's a way of forcing a contract between the class designer and the users of that class. If we wish to create a concrete class (a class that can be instantiated) from an abstract class we must declare and define a matching member function for each abstract member function of the base class.
As mentioned, it's a way of defining an interface to which derived classes must adhere. Their example of the Vehicle abstract class is very apropos: you'd never have just a Vehicle in real life, you'd have a Ford Explorer or a Toyota Prius, but those both conform to (for the sake of argument) a base set of functionality that being a Vehicle might define. But, you can't just go to the Vehicle dealership and drive a Vehicle off the lot. Thus, you'd never want to be able to construct and use a base Vehicle object where you'd really want a specialized, derived object.
This offers the best way in C++ to define an interface without any default implementation.
C++ does not have C#'s interface concept.
It's the equivalent of what Java turned into "interfaces". Basically, it implies that the class itself is not usable - you need to override all pure methods.
An example is MFC's CView class which has a pure OnDraw method - the basic CView doesn't do anything and is as such useless. You have to override OnDraw.
(Btw - it is still possible to provide an implementation for a pure method, and subclassed implementations can fall back to it, but they still have to provide their own override.)
They are used as a base class in a class hierarchy design.
Abstract classes are used to define a clean interface for all derived classes.
At design stage, abstract classes define an interface, per specification and derived classes implement the desired functionality accordingly.
Also using abstract classes instead of "normal" classes helps separating the implementation details from the interface.
A concrete class implements an interface, but the abstract class defines it. You could use a concrete class as a base class in your design but abstract classes are not meant to be used directly in code and can not be instantiated. They serve as prototype.
By using the "normal" class as you say, you have to define an implementation for all methods.
Don't think of it at the class level.
Look at the method, and think of what it should do in the default case:
virtual std::string getName() const = 0;
What would be a right implementation for this method ? There is none than I can think of.
By marking it "pure virtual", you ensure that if the user ever get an instance of a class derived from your interface, then this method will have a sensible behavior.
The only other way to do this would be a throw NotImplemented("getName"); body, but then you'd discover the issue at runtime, not at compile-time, which is not as nice :)

Parameterized Factory & product classes that cannot be instantiated without the Factory

I'm working on implementing a Factory class along the lines of what is proposed in this response to a previous question:
Factory method implementation - C++
It's a Factory that stores a map from strings to object creation functions so I can request different types of objects from the factory by a string identifier. All the classes this factory produces will inherit from an abstract class (Connection) providing a common interface for connections over different protocols (HTTPConnection, FTPConnection, etc...)
I have a good grasp of how the method linked to above works and have got that working.
Where I'm having problems is trying to figure out a mechanism to prevent instantiation of the Connection objects without using the Factory. In order for the Factory to do it's work, I need to provide it an object creation function to store in it's map. I can't provide it the constructor because you can't make function pointers to constructors. So, as in the link above, there has to be a seperate object creation function to return new objects. But to do this, I need to make this creation function either a static method of the class, which the client code would be able to access, or a seperate function which would require either a)that the constructor of the Connection classes be public, or b) make the constructor private and make a non class member creation function be a friend, which isn't inherited and can't be enforced by the abstract base class.
Similarly, if I just made the Factory class friends with the Connection classes it was supposed to produce so it could access their private constructors, that would work, but I couldn't enforce through the abstact base class because friends aren't inherited. Each subclass would have to explicitly be friends with the Factory.
Can anyone suggest a method of implementing what I've described above?
To reiterate the requirements:
1 - Factory that produces a variety of objects all derived from the same base class based on passed in identifier to the Factory's Create method.
2 - All the subclasses that the factory will need to produce will automatically register a creation function and identifier with the factory (see linked SO answer above)
3 - All the subclasses that the factory will produce should not be instantiable (instantiatable?) without going through the Factory
4 - Enforce #3 explicitly as part of the abstract base class using inheritance. Remove the possibility for someone to subclass from the abstract base class while also providing mechanisms to freely instantiate objects.
The overall goal of what I'm trying to achieve is to allow new Connection types to be added to the hierarchy without having to change the Factory class in any way, while also forcing all the subclasses of Connection to not be instantiable directly by client code.
I'm open to the possibility that this is not the best way to achieve what I want, and suggestions of other alternatives are welcome.
EDIT - Will add some code snippets to this when I get home to hopefully make this clearer.
If I understand you correctly I think you can put some of what you want in the METADECL macro I mention in my answer you link to, ie define a static creator function that is a friend or declare it as a static method. This will make it possible for you to restrict the constructor from public use etc.
Below I try to point out where the METADECL (and METAIMPL) should be. I leave it for you to implement what you need there (I believe in you)
Header file
class MySubClass : public FactoryObjectsRoot {
METADECL(MySubClass) // Declare necessary factory construct
:
:
};
Source file
METAIMPL(MySubClass) // Implement and bootstrap factory construct