I want to use an abstract base class for the purpose of interfacing and usability. This abstract base class will be used as the parent class for several different derived classes, each of which has need of a certain subset of the pure virtual functions in the abstract base class. An outline of my scheme is as follows.
abstractclass.hpp
AbstractClass{
/* Declaration */
void pureVirt1() = 0;
void pureVirt2() = 0;
void pureVirt3() = 0;
};
derivedclass1.hpp
DerivedClass1{
/* Declaration */
void pureVirt1();
};
derivedclass2.hpp
DerivedClass2{
/* Declaration */
void pureVirt2();
};
derivedclass3.hpp
DerivedClass3{
/* Declaration */
void pureVirt3();
};
Given the current implementation, all of the above classes are abstract classes and no objects can be created from these classes. In the past, I have resolved this issue with preprocesser directives around each virtual function.
abstractclass.hpp
AbstractClass{
#ifdef _1
void purVirt1()=0;
#endif
...
And at the top of each derived class's header file, before the include to abstractclass.hpp I would write something like the following
derivedclass1.hpp
#define _1
#include"abstractclass.hpp"
...
This worked when I was working with small projects and not writing make files. The header for the abstract class was effectively altered based on which derived class was using it, so long as I kept my directives in the correct place. Now that I am using makefiles, this does not work. abstractcalss.cpp is compiled without any of the virtual functions in the header file because it is compiled separately from the derivedclass. I am looking for a good workaround for this.
I want this functionality because I have many similar derived classes from this abstract base class that are used by a variety of other tools I have written. I want to keep these other tools as simple as possible and just use pointers to the abstract class instead of writing template classes for everything.
--Further information
I have a situation where AbstractClass is in a has-a relationship with SubAbstractClass and is implemented by use of having a pointer to SubAbstractClass in AbstractClass. Furthermore, for each of the derived classes there is a similar has-a relationship with SubDerivedClass1, SubDerivedClass2, … I don’t want to write containers for every new class that I create, especially because I can combine my derived classes to create novel classes that are important and functional and any such combination of new classes would require creating the appropriate set of subclasses. To this end, it is useful to have an ABC to allow the pointers to be declared once and work for any derived class.
[...] several different derived classes, each of which has need of a
certain subset of the pure virtual functions in the abstract base
class.
Obviously, this won't work. Moreover, your attempts to make things simpler are, in my opinion, having the opposite effect. You are making things much more complex by introducing preprocessor black magic to comment-in and comment-out specific parts of the interfaces.
You're swimming upstream without a paddle here. Instead of having one interface class to which you add and remove methods piecemeal, just develop several different interface classes that do a better job of modularizing the functionality:
AbstractClass1{
/* Declaration */
void pureVirt1() = 0;
};
AbstractClass2{
/* Declaration */
void pureVirt2() = 0;
};
AbstractClass3{
/* Declaration */
void pureVirt3() = 0;
};
Trying to make one universal, God class that you blow pieces off of to suit specific modules's needs is going to eventually bite you, and hard. Consider what might happen when you need two instantiations of the interface in the same translation unit, but each of those instantiations have different pieced #defineed in. Sounds like a nightmare to me.
Start with a common base class.
class AbstractBaseClass {
// common stuff goes here
};
Then, create abstract interfaces for the sub-versions:
class AbstractSubClass1:public AbstractBaseClass {
public:
void pureVirt1() = 0;
};
class AbstractSubClass2:public AbstractBaseClass {
public:
void pureVirt2() = 0;
};
class AbstractSubClass3:public AbstractBaseClass {
public:
void pureVirt3() = 0;
};
which contain the abstract pureVirt methods.
Finally, derive your implementation classes form the sub classes:
class Derived1 : public AbstractSubClass1 {
virtual void pureVirt1() override; // override if your compiler supports it
};
class Derived2 : public AbstractSubClass2 {
virtual void pureVirt2() override; // override if your compiler supports it
};
class Derived3 : public AbstractSubClass3 {
virtual void pureVirt3() override; // override if your compiler supports it
};
now, objects that know you are a particular sub class can access the pureVirtX member. Those that don't only have access to the common AbstractBaseClass interface (whatever that is - you mention that some code doesn't need to know about these particular virtual methods).
Related
I have following dilemma:
I have a full abstract class. Each inheriting class will need 3 same parameters. Each of them will additionally need other specific parameters.
I could:
1) implement a common constructor for initializing 3 common parameters in my base class, but then I have to make non-abstract getters for corresponding fields (they are private).
OR
2) leave my base class abstract and implement constructors in inherited classes, but then I have to make it in each class fields for common parameters.
Which is a better approach? I don't want to use protected members.
An abstract class is one who has at least one pure virtual (or, as you call it, abstract) function. Having non-abstract, non-virtual functions does not change the fact that your class is abstract as long as it has at least one pure virtual function. Go for having the common functionality in your base class, even if it is abstract.
One way to avoid code duplication without polluting your abstract interface with data members, is by introducing an additional level of inheritance:
// Only pure virtual functions here
class Interface {
public:
virtual void foo() = 0;
};
// Things shared between implementations
class AbstractBase : public Interface {
};
class ImplementationA : public AbstractBase {
};
class ImplementationB : public AbstractBase {
};
If your class looks like this, a pure abstract class:
class IFoo {
public:
virtual void doThings() = 0;
}
class Foo {
public:
Foo(std::string str);
void doThings() override;
}
The value your inheritance has is to provide you with the oppurtunity to subsitute Foo with another at runtime, but hiding concrete implementations behind interfaces. You can't use that advantage with Constructors, there's no such thing as a virtual constructor (that's why things like the Abstract Factory Pattern exist). All your implementations of Foo take a std::string and all your implementations of doThings use that string? Great, but that's a coincidence not a contract and doesn't belong in IFoo.
Lets talk about if you've created concrete implementations in IFoo, so that it's a abstract class and not a pure abstract class (IFoo would be a bad name now btw). (*1) Lets assume using inheritance to share behaviour was the correct choice for you class, which is sometimes true. If the class has fields that need to be initialised create a protected constructor (to be called from every child implementation) and remove/ommit the default one.
class BaseFoo {
private:
std::string _fooo;
protected:
BaseFoo(std::string fooo) : _fooo(fooo) {}
public:
virtual void doThings() = 0;
std::string whatsTheBaseString() { return _fooo;}
}
Above is the way you correctly pass fields needed by a base class from the child constructor. This is a compile time guarantee that a child class will 'remember' to initialize _fooo correctly and avoids exposing the actual member fooo to child classes. Trying to initialize _fooo in all the child constructors directly would be incorrect here.
*1) Quickly, why? Composition may be a better tool here?.
I've just learned about polymorphism in my OOP Class and I'm having a hard time understanding how abstract base classes are useful.
What is the purpose of an abstract class? What does defining an abstract base class provide that isn't provided by creating each necessary function in each actual class?
The purpose of an abstract class is to define a common protocol for a set of concrete subclasses. This is useful when defining objects that share code, abstract ideas, etc.
Abstract classes have no instances. An abstract class must have at least one deferred method (or function). To accomplish this in C++, a pure virtual member function is declared but not defined in the abstract class:
class MyClass {
virtual void pureVirtualFunction() = 0;
}
Attempts to instantiate an abstract class will always result in a compiler error.
"What does defining an abstract base class provide that isn't provided
by creating each necessary function in each actual class?"
The main idea here is code reuse and proper partitioning across classes. It makes more sense to define a function once in a parent class rather than defining over and over again in multiple subclasses:
class A {
void func1();
virtual void func2() = 0;
}
class B : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
class C : public A {
// inherits A's func1()
virtual void func2(); // Function defined in implementation file
}
Having an abstract class like "Dog" with a virtual method like "bark" allows all classes that inherit from Dog to have their bark code called in the same way, even though the Beagle's bark is implemented way differently than the Collie's.
Without a common abstract parent (or at least a common parent with a bark virtual method) it'd be difficult to do the following:
Have a Vector of type Dog that contains Collies, Beagles, German Shepherds etc and make each of them bark. With a Vector of Dogs that contains Collies, Beagles, German Shepherds all you would have to do to make them all bark is to iterate through in a for loop and call bark on each one. Otherwise you'd have to have a separate Vector of Collies, Vector of Beagles etc.
If the question is "why make Dog abstract when it could be concrete, have a virtual bark defined with a default implementation that can be overriden?", the answer would be that this may be acceptable sometimes -- but, from a design perspective, there really isn't any such thing as a Dog that isn't a Collie or a Beagle or some other breed or mix so although they are all Dogs, there is not one of them in reality that is a Dog but not some other derived class too. Also, since dogs barking is so varied from one breed to another, there is unlikely to be any real acceptable default implementation of bark that would be acceptable for any decent group of Dogs.
I hope this helps you understand the purpose: yes, you're going to have to implement bark in each subclass anyway, but the common abstract ancestor lets you treat any subclass as a member of a base class and invoke behaviors that may be conceptually similar like bark but in fact have very different implementations.
Abstract classes allow for compile time protocol enforcement. These protocols define what it means to be a part of a class family.
Another way to think of it is that a abstract class is a contract that your implementing classes must fulfill. If they do not fulfill this contract they cannot be part of the class family and they must be modified to conform to the contract. The provided contract may provide default functionality, but it also leaves it up to the sub-class to define more specific or different functionality while still remaining within the scope of the contract.
For small projects this may not seem useful but for large projects it provides conformity and structure as it provides documentation through the abstract class contract. This makes for more maintainable code and makes for the sub-classes to each have the same protocol making using and developing new sub-classes easier.
The purpose of an abstract class is to provide an appropriate base class from which other classes can inherit. Abstract classes cannot be used to instantiate objects and serves only as an interface. Attempting to instantiate an object of an abstract class causes a compilation error. (because vtable entry is not filled with memory location for virtual function we mentioned in Abstract Class)
Thus, if a subclass of an ABC needs to be instantiated, it has to implement each of the virtual functions, which means that it supports the interface declared by the ABC. Failure to override a pure virtual function in a derived class, then attempting to instantiate objects of that class, is a compilation error.
Example:
class mobileinternet
{
public:
virtual enableinternet()=0;//defines as virtual so that each class can overwrite
};
class 2gplan : public mobileinternet
{
private:
int providelowspeedinternet(); //logic to give less speed.
public:
void enableinternet(int) {
// implement logic
}
};
//similarly
class 3gplan : public enableinternet
{
private: high speed logic (different then both of the above)
public:
/* */
}
here in this example, you can understand.
I have a dog. Abstract class dog with a method bark. My particular dog makes one bark. Other dogs bark in a different way. So defining a dog in the abstract way is useful.
Abstract classes are used to define an interface to be implemented. See some references:
http://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes
An abstract class AbstractClass as a base class is needed when there is functionality that is desired for all objects that have a type deriving from AbstractClass, but cannot sensibly be implemented on the AbstractClass itself.
The old and somewhat artificial OO example of having a base class Vehicle with derived classes Car, Motorcycle, ... provides a good example here, say you want a method move() - you can implement the way that a Car or a Motorcycle moves, but Vehicles don't move in a generic way, so Vehicle::move() will have to be pure virtual and Vehicle therefore abstract.
why don't we create each necessary function in each class ? (C++)
You have to create each necessary function marked as abstract in each derived class.
If you question is, why to create abstract function in abstract class?
It allows strict run time polymorphism.
Also read Interface vs Abstract Class (general OO)
abstract class dog
{
bark();
}
// function inside another module
dogbarking(dog obj)
{
dog.bark(); // function will call depend up on address inside the obj
}
// our class
ourclass: inherit dog
{
bark()
{
//body
}
}
main()
{
ourclass obj;
dogbarking(obj);
}
we can see that dogbarking is a function written in another module. it knows only the abstract class dog. even though it can call the function bark inside ourclass. in main function we create object of ourclass and pass to function dogbarking where it received using reference object of abstract class dog.
Imagine you have two methods for displaying a string:
DisplayDialog(string s);
PrintToConsole(string s);
And you want to write some code that can be switched between these two methods:
void foo(bool useDialogs) {
if (useDialogs) {
DisplayDialog("Hello, World!");
} else {
PrintToConsole("Hello, World!");
}
if (useDialogs) {
DisplayDialog("The result of 2 * 3 is ");
} else {
PrintToConsole("The result of 2 * 3 is ");
}
int i = 2 * 3;
string s = to_string(i);
if (useDialogs) {
DisplayDialog(s);
} else {
PrintToConsole(s);
}
}
This code is tightly coupled to the specific methods used for displaying the string. Adding an additional method, changing how the method is selected, etc. will affect every piece of code that uses this. This code is tightly coupled to the set of methods we use to display strings.
Abstract base classes are a way of decoupling code that uses some functionality from the code that implements that functionality. It does this by defining a common interface to all the various ways of doing the task.
class AbstractStringDisplayer {
public:
virtual display(string s) = 0;
virtual ~AbstractStringDisplayer();
};
void foo(AbstractStringDisplayer *asd) {
asd->display("Hello, World!");
asd->display("The result of 2 * 3 is ");
int i = 2 * 3;
string s = to_string(i);
asd->display(s);
}
int main() {
AbstractStringDisplayer *asd = getStringDisplayerBasedOnUserPreferencesOrWhatever();
foo(asd);
}
Using the interface defined by AbstractStringDisplayer we can create and use as many new ways of displaying strings as we want, and code that uses the abstract interface won't need to be changed.
So I have these classes. There's one base class, but it has/will have lots and lots of derivatives, and those derivative classes will be able to have derivatives as well. I'd like to be able to have a function that writes their binary data to a file, but I'm not sure how to do this with lots and lots of derived classes.
I was thinking something along the lines of:
void writeData(ofstream & _fstream)
{
_fstream.write()//etc..
}
But then each derived class that implemented this method would have to write all of it's parent class's data, and that would be duplicating a lot of code.
What's the best way to do this without rewriting all of the previously written writeData() code?
You can call the base class implementation from the derived class implementation:
void Derived::writeData(ofstream & _fstream)
{
// Base class writes its data
Base::writeData(_fstream);
// now I can write the data that is specific to this Derived class
_fstream.write()//etc..
}
Derived class can call base write methods to avoid code duplication. In fact, that may be the only way to go if some parent's data is private but still is indirectly used.
If you want to avoid re-engineering all the derived class' implementation of the serialization functions, you can go in the other direction, from the base to the derived classes:
In your base class provide a non-virtual function to start the serialization process. Client code calls this function via a pointer (or reference). Also provide a virtual function that does the serialization for the subclass. Call that function from the base class' Serialize function.
(EDIT) If you want to provide default functionality for serializing the subclasses, but still want to be able to provide specialized functionality for specific cases, then the function that serializes the subclasses need not be pure virtual. However, by my reading of your OP it seemed to me that every subclass would need to be required to provide this functionality. To model that requirement, I have made the DoSerialize function pure virtual here.
Example:
class Base
{
public:
void Serialize() const;
virtual void DoSerialize() = 0;
};
class Derived : public Base
{
public:
void DoSerialize() { /* MAGIC HAPPENS */ };
};
void Base::Serialize() const
{
/* .. do serialization of base class here, or at the end -- whichever is appropriate .. */
this->DoSerialize(); // serialize the derived class
}
/* ... */
Base* GetObject()
{
/* ... */
}
int main()
{
Base* obj = GetObject();
obj->Serialize();
}
Ultimately, it is the responsibility of each derived class to make sure that it has been serialized properly. A derived class may need to serialize some data before or after the base class, depending on its purpose. It may also want to totally override the way the base class data is serialized.
Look at it this way - the function being performed here is serialization and de-serialization. The critical thing here is that it needs to be performed correctly. Therefore, the only class that is in a good position to do this is the one with complete knowledge. In other words, its your derived class.
So, there are times when you will have to call Base::writeData(), but whether or not you do that should be left totally up to the derived class. Remember, what you want is for your class hierarchy to satisfy some basic design principles. Once you've got that, it should be relatively easy.
Say I have an abstract class "Base", of which another abstract class "Subclass" extends. Base has a number of abstract member functions, and "Subclass" implements a number of them, but leaves it's own subclasses to provide the implementation of others. Should I include the signature of the member functions which I don't implement in the intermediate class or not?
In other words, assuming I have the following class structure:
Car.hpp:
class Car {
public:
virtual std::string getMake() = 0;
virtual std::string getType() = 0;
virtual ~Car { };
}
SportsCar.hpp:
class SportsCar : public Car {
public:
std::string getType();
// Do I need to specify virtual std::string getMake() = 0; here?
}
SportsCar.cpp:
std::string SportsCar::getType()
{
return "sports";
}
FerrariSportsCar.hpp:
class FerrariSportsCar : public SportsCar {
public:
std::string getMake();
}
FerrariSportsCar.cpp:
std::string FerrariSportsCar::getMake()
{
return "ferrari";
}
Should I still need include virtual std::string getMake() = 0; in SportsCar.hpp?
The code compiles whether I include it or not, and the program seems to execute exactly the same.
You don't need to specify the abstract method again in the intermediate class. It will be inherited by the intermediate class as pure and still require it to be overridden in a further child.
Note that your intermediate class will still be abstract and you couldn't create instances of it.
Since it compiles both ways, this is somewhat a matter of style. I follow a general rule of "do as little work as possible". I think it applies here.
Omitting it will cause a compilation error for those who try to subclass SportsCar without implementing getMake(). Not repeating the definition in the intermediate class makes it easier to change the interface in the future.
There is one case where I would potentially put the intermediate pure virtual for readability purposes, which is when you have something like:
template<typename T>
class Foo : public T {...};
In this case, since it's difficult to find out the type of T, there's some value in putting the extra definition.
Not only you don't need to re-specify pure virtual member function declarations in intermediate classes of your hierarchy, but I would advise against doing so: when programming in C++ one has to get used to look for things in all the places they might legitimately be. By the way this is true also of many other programming languages.
Why would I want to define a C++ interface that contains private methods?
Even in the case where the methods in the public scope will technically suppose to act like template methods that use the private methods upon the interface implementation, even so, we're telling the technical specs. right from the interface.
Isn't this a deviation from the original usage of an interface, ie a public contract between the outside and the interior?
You could also define a friend class, which will make use of some private methods from our class, and so force implementation through the interface. This could be an argument.
What other arguments are for defining a private methods within an interface in C++?
The common OO view is that an interface establishes a single contract that defines how objects that conform to that interface are used and how they behave. The NVI idiom or pattern, I never know when one becomes the other, proposes a change in that mentality by dividing the interface into two separate contracts:
how the interface is to be used
what deriving classes must offer
This is in some sense particular to C++ (in fact to any language with multiple inheritance), where the interface can in fact contain code that adapts from the outer interface --how users see me-- and the inner interface --how I am implemented.
This can be useful in different cases, first when the behavior is common but can be parametrized in only specific ways, with a common algorithm skeleton. Then the algorithm can be implemented in the base class and the extension points in derived elements. In languages without multiple inheritance this has to be implemented by splitting into a class that implements the algorithm based in some parameters that comply with a different 'private' interface. I am using here 'private' in the sense that only your class will use that interface.
The second common usage is that by using the NVI idiom, it is simple to instrument the code by only modifying at the base level:
class Base {
public:
void foo() {
foo_impl();
}
private:
virtual void foo_impl() = 0;
};
The extra cost of having to write the dispatcher foo() { foo_impl(); } is rather small and it allows you to later add a locking mechanism if you convert the code into a multithreaded application, add logging to each call, or a timer to verify how much different implementations take in each function... Since the actual method that is implemented in derived classes is private at this level, you are guaranteed that all polymorphic calls can be instrumented at a single point: the base (this does not block extending classes from making foo_impl public thought)
void Base::foo() {
scoped_log log( "calling foo" ); // we can add traces
lock l(mutex); // thread safety
foo_impl();
}
If the virtual methods were public, then you could not intercept all calls to the methods and would have to add that logging and thread safety to all the derived classes that implement the interface.
You can declare a private virtual method whose purpose is to be derivated. Example :
class CharacterDrawer {
public:
virtual ~CharacterDrawer() = 0;
// draws the character after calling getPosition(), getAnimation(), etc.
void draw(GraphicsContext&);
// other methods
void setLightPosition(const Vector&);
enum Animation {
...
};
private:
virtual Vector getPosition() = 0;
virtual Quaternion getRotation() = 0;
virtual Animation getAnimation() = 0;
virtual float getAnimationPercent() = 0;
};
This object can provide drawing utility for a character, but has to be derivated by an object which provides movement, animation handling, etc.
The advantage of doing like this instead of provinding "setPosition", "setAnimation", etc. is that you don't have to "push" the value at each frame, instead you "pull" it.
I think this can be considered as an interface since these methods have nothing to do with actual implementation of all the drawing-related stuff.
Why would I want to define a C++
interface that contains private
methods?
The question is a bit ambiguous/contradictory: if you define (purely) an interface, that means you define the public access of anything that connects to it. In that sense, you do not define an interface that contains private methods.
I think your question comes from confusing an abstract base class with an interface (please correct me if I'm wrong).
An abstract base class can be a partial (or even complete) functionality implementation, that has at least an abstract member. In this case, it makes as much sense to have private members as it makes for any other class.
In practice it is rarely needed to have pure virtual base classes with no implementation at all (i.e. base classes that only define a list of pure virtual functions and nothing else). One case where that is required is COM/DCOM/XPCOM programming (and there are others). In most cases though it makes sense to add some private implementation to your abstract base class.
In a template method implementation, it can be used to add a specialization constraint: you can't call the virtual method of the base class from the derived class (otherwise, the method would be declared as protected in the base class):
class Base
{
private:
virtual void V() { /*some logic here, not accessible directly from Derived*/}
};
class Derived: public Base
{
private:
virtual void V()
{
Base::V(); // Not allowed: Base::V is not visible from Derived
}
};