I'm now learning C++, the OO side, and I see this all the time:
class SomeClass{
virtual void aMethod()=0;
}
class AnotherClass{
void anotherMethod(){/*Empty*/}
}
class SomeClassSon : public SomeClass{
void aMethod(){/*Also Empty*/}
}
what is the difference between the 3 methods? The virtual equals zero, the empty one, and the virtual, since it is inherited, empty one.
Why can't I just make the SomeClassSon method like the father, virtual void equals zero?
For your
class SomeClass{
virtual void aMethod()=0;
}
the presence of a pure virtual method makes your class abstract. Once you have one such pure virtual method, =0, in your class, you cannot instantiate the class. What is more, any derived class must implement the pure virtual aMethod(), or it becomes an abstract class as well.
In your derived class, you overwrite the pure virtual method from above, and this makes the derived class non abstract. You can instantiate this derived class.
But, in derived class, method's body is empty, right? That's why your question makes sense: why not make the class pure virtual as well. Well, your class may entail other methods. If so, SomeClass cannot be instantiated (there is a pure virtual method), whereas child class SomeClassSon can be.
Same applies to your AnotherClass, which can be instantiated, contrary to SomeClass.
The difference is that virtual void aMethod() = 0 is a pure virtual function, meaning that:
SomeClass becomes an abstract base class,
meaning it cannot be instantiated.
Any class which inherits from SomeClass must implement aMethod, or it too becomes an abstract base class which cannot be instantiated
Note that any class with one or more pure virtual functions is automatically an abstract base class.
The "equals 0" you're referring to is called "pure virtual". It's a function that the child that wants to be instantiated HAS to implement as opposed to providing base functionality meaning that the parent class is going to define functionality that has to exist but that the parent has no knowledge of how the child will do it. Note that this makes the class abstract in that it cannot be instantiated. For example I may want to define a "Mammal" class I can inherit from and I want its children to act a certain way - but I can't simply make a "Mammal". Instead I would create a "Giraffe" class and make sure it acts like it's supposed to.
It's also explained at this SO question.
The "Empty" function you're referring to is instead functionality where the function is defined and can be called - but does nothing.
the declaration aMethod()=0 tells the compiler that this method must be provided for in subclasses. Any subclass that does not implement the method can not be instantiated. This helps you ensure any objects of the base class will have the method implemented.
A pure virtual function (your first example, with the =0) means that function must be overridden in a derived class for an object of that class to be instantiated.
The second is basically just a member function that does nothing. Since the function has a different name and the class isn't related to SomeClass, the two don't affect each other at all.
The third overrides the pure virtual function, so it's possible to instantiate SomeClassSon, but in the derived class the overridden function does nothing.
A pure virtual makes the class abstract. An empty non-virtual method doesn't do anything - it just leads to a linker error if you attempt to call it. By contrast, you can't attempt to call a pure virtual (unless you attempt to call it from a constructor, which is bad anyway) because the compiler won't let you create that object.
There's also a logical difference - the method marked virtual will be virtual through the inheritance chain - the others are just regular methods.
Related
This may seem like a simple question, but I can't find the answer anywhere else.
Suppose I have the following:
class Abstract {
public:
virtual void foo() = 0;
virtual void bar();
}
class Derived : Abstract {
public:
virtual void foo();
}
Is it ok that class Derived does not implement the bar() function?
What if not ALL of my derived classes need the bar() function, but some do.
Do all of the virtual functions of an abstract base class need to be implemented in the derived classes, or just the ones that are pure virtual?
Thanks
Derived classes do not have to implement all virtual functions themselves. They only need to implement the pure ones.1 That means the Derived class in the question is correct. It inherits the bar implementation from its ancestor class, Abstract. (This assumes that Abstract::bar is implemented somewhere. The code in the question declares the method, but doesn't define it. You can define it inline as Trenki's answer shows, or you can define it separately.)
1 And even then, only if the derived class is going to be instantiated. If a derived class is not instantiated directly, but only exists as a base class of more derived classes, then it's those classes that are responsible for having all their pure virtual methods implemented. The "middle" class in the hierarchy is allowed to leave some pure virtual methods unimplemented, just like the base class. If the "middle" class does implement a pure virtual method, then its descendants will inherit that implementation, so they don't have to re-implement it themselves.
Only the pure virtual methods have to be implemented in derived classes, but you still need a definition (and not just a declaration) of the other virtual methods. If you don't supply one, the linker might very well complain.
So, just putting {} after your optional virtual method gives you an empty default implementation:
class Abstract {
public:
virtual void foo() = 0; // pure virtual must be overridden
virtual void bar() {} // virtual with empty default implementation
};
class Derived : Abstract {
public:
virtual void foo();
};
A more involved default implementation would go into a separate source file though.
The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined.
Simply put the rule is:
If your derived class overiddes the Base class virtual method then it should provide a definition as well, If not then the Base class should provide the definition of that method.
As per the above rule in your code example, virtual void bar(); needs a definition in the Base class.
Reference:
C++03 Standard: 10.3 Virtual functions [class.virtual]
A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).
So either you should make the function pure virtual or provide a definition for it.
The gcc faq doccuments it as well:
The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined, but does not require any diagnostic for violations of this rule [class.virtual]/8. Based on this assumption, GCC will only emit the implicitly defined constructors, the assignment operator, the destructor and the virtual table of a class in the translation unit that defines its first such non-inline method.
Therefore, if you fail to define this particular method, the linker may complain about the lack of definitions for apparently unrelated symbols. Unfortunately, in order to improve this error message, it might be necessary to change the linker, and this can't always be done.
The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.
Yes, that's fine ... you only need to implement any pure virtual functions in order to instantiate a class derived from an abstract base class.
Yes, Its correct that a Derived class has to OVERRIDE the function which is Pure Virtual in the Parent Class. Parent class having a Pure Virtual Function is called Abstract Class only because it's Child class must give their own body of the Pure Virtual Function.
For the Normal Virtual Functions:-
Its not necessary to override them further, as some child class may have that function, some may not have.
Main purpose of Virtual Function mechanism is Run Time Polymorphism, whether main purpose of Pure Virtual Function(Abstract Class) is to make it mandatory to have the same name Function with own's body.
I'm looking at the following code in my book:
class Shape
{
public:
Shape(){}
~Shape(){}
virtual long getArea() = 0; // Pure virtual function
virtual long getPerim() = 0;
virtual void draw() = 0;
};
Now it says that these virtual functions make the class abstract (which I understand from Java), so the class cannot be instantiated.
However, it says: "a class is in abstract data type by including one or more virtual functions in the class declaration."
Would this mean if I declared a class with ONE pure virtual function:
class Shape
{
public:
Shape(){}
~Shape(){}
virtual long getArea() = 0; // Only pure virtual function
virtual long getPerim(){}
virtual void draw(){}
};
does the whole class become abstract? Because if a class has 100+ methods, it'll be tedious to write =0 for every method if I decide to make it abstract later.
Yes, a single pure virtual method is enough to make the class abstract.
Moreover, you can always make the destructor pure virtual if no other methods are suited to be pure.
Also, your destructor should probably be virtual, since you're obviously going to inherit from this class. This is mandatory if you plan on deleting objects of a derived type through a pointer to a base type.
You are correct in that one pure virtual method is enough to make the class abstract. That means you must implement the method in a derived class to instantiate an instance (of the derived class).
I have issues with your "class with 100+ methods". Usually this is a sign of very poor design.
I also have issues with your "tedious to write =0 for every method" attitude. Firstly I do not see why it is any more tedious to write =0 than it is to write {} as a default no-op implementation (and if the method returns anything, like getPerim() does, you risk undefined behaviour by not returning something). Primarily though, business logic dictates whether or not there is a default behaviour, and not the effort of writing.
Remember the Liskov substitution principle: Although one cannot have an instance of your base class, someone will have a pointer or reference to one, and call virtual methods on it without having to know what class they really have. (Incidentally Liskov was female, first name Barbara, and stated this principle sometime around 1983).
Your abstract base class should almost certainly have a virtual destructor, by the way.
Methods that will not change the state of the class should be declared const.
Marking a function pure doesn't just make the class abstract, it makes any derived class that doesn't override the function also abstract.
So, if you want to force derived classes to implement all those functions, then make them all pure. If it makes sense for a derived class to implement only getArea and not the other two, then only mark getArea pure. In this example I suspect that it doesn't make sense, since if all the derived class has added is a way to compute the area, there's still no way that the base class can compute the perimeter.
Declaring a method as pure virtual means that classes that inherit your class will have to implement that method or leave it pure virtual, in which case the derived class will also be an abstract class that cannot be instantiated.
Also, as Luchian said previously, you should always declare the destructor as virtual for every class that will be inherited.
This may seem like a simple question, but I can't find the answer anywhere else.
Suppose I have the following:
class Abstract {
public:
virtual void foo() = 0;
virtual void bar();
}
class Derived : Abstract {
public:
virtual void foo();
}
Is it ok that class Derived does not implement the bar() function?
What if not ALL of my derived classes need the bar() function, but some do.
Do all of the virtual functions of an abstract base class need to be implemented in the derived classes, or just the ones that are pure virtual?
Thanks
Derived classes do not have to implement all virtual functions themselves. They only need to implement the pure ones.1 That means the Derived class in the question is correct. It inherits the bar implementation from its ancestor class, Abstract. (This assumes that Abstract::bar is implemented somewhere. The code in the question declares the method, but doesn't define it. You can define it inline as Trenki's answer shows, or you can define it separately.)
1 And even then, only if the derived class is going to be instantiated. If a derived class is not instantiated directly, but only exists as a base class of more derived classes, then it's those classes that are responsible for having all their pure virtual methods implemented. The "middle" class in the hierarchy is allowed to leave some pure virtual methods unimplemented, just like the base class. If the "middle" class does implement a pure virtual method, then its descendants will inherit that implementation, so they don't have to re-implement it themselves.
Only the pure virtual methods have to be implemented in derived classes, but you still need a definition (and not just a declaration) of the other virtual methods. If you don't supply one, the linker might very well complain.
So, just putting {} after your optional virtual method gives you an empty default implementation:
class Abstract {
public:
virtual void foo() = 0; // pure virtual must be overridden
virtual void bar() {} // virtual with empty default implementation
};
class Derived : Abstract {
public:
virtual void foo();
};
A more involved default implementation would go into a separate source file though.
The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined.
Simply put the rule is:
If your derived class overiddes the Base class virtual method then it should provide a definition as well, If not then the Base class should provide the definition of that method.
As per the above rule in your code example, virtual void bar(); needs a definition in the Base class.
Reference:
C++03 Standard: 10.3 Virtual functions [class.virtual]
A virtual function declared in a class shall be defined, or declared pure (10.4) in that class, or both; but no diagnostic is required (3.2).
So either you should make the function pure virtual or provide a definition for it.
The gcc faq doccuments it as well:
The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined, but does not require any diagnostic for violations of this rule [class.virtual]/8. Based on this assumption, GCC will only emit the implicitly defined constructors, the assignment operator, the destructor and the virtual table of a class in the translation unit that defines its first such non-inline method.
Therefore, if you fail to define this particular method, the linker may complain about the lack of definitions for apparently unrelated symbols. Unfortunately, in order to improve this error message, it might be necessary to change the linker, and this can't always be done.
The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.
Yes, that's fine ... you only need to implement any pure virtual functions in order to instantiate a class derived from an abstract base class.
Yes, Its correct that a Derived class has to OVERRIDE the function which is Pure Virtual in the Parent Class. Parent class having a Pure Virtual Function is called Abstract Class only because it's Child class must give their own body of the Pure Virtual Function.
For the Normal Virtual Functions:-
Its not necessary to override them further, as some child class may have that function, some may not have.
Main purpose of Virtual Function mechanism is Run Time Polymorphism, whether main purpose of Pure Virtual Function(Abstract Class) is to make it mandatory to have the same name Function with own's body.
So here is the box I am in. I want to understand why it is important to have a "virtual destructor inside your interface class". You will see why that stuff is in quotes if you can hang to the end... I also want to get all the vocabulary absolutely correct. Here is where I am at with the process so far:
Sometimes you have base classes, sometimes you have derived classes which inherit from base classes.
If you have a base-pointer that finds itself pointing to a derived-object, and further you want a member function call made from that base-pointer-pointing-to-a-derived-object to behave as if it had actually been called from the derived object, then the member function you call had better be declared virtual in the base class.
An interface is any class with only pure virtual functions. If you derive a new class from this interface class and implement all the pure virtual functions, then you can finally create an instance of the derived class.
You can never have an instance of an interface class, BUT you can have an instance of a pointer-to-interface-class.
In the case where you have a pointer-to-interface-class that actually points to an object of the derived class (actually, I guess it would always have to if #4 is correct), and if you decide to delete that object through your pointer, then if you don't have a "virtual destructor inside your interface class", your intention to destroy the derived object will only be executed as a call to destroy the base object (i.e. the interface class) and since there is no virtual destructor, things won't ever get to the point where the destructor for the derived object is actually called -- thus causing memory leaks.
Phew. Okay, if that sounds right, onto my question. Is it enough just to declare a virtual destructor inside your interface like this:
virtual ~iFace();
That looks wrong to me... so what happens if you make the destructor pure virtual like this:
virtual ~iFace() = 0;
Since they are just declarations, do either of these count for being a "virtual destructor inside your interface class"? Can you even have a declared but un-defined destructor? Only if it is pure virtual I would guess...
Anyway, so getting back to the title question... I really am going as fast as I can... Here is the money shot... If your "virtual destructor inside your interface class" requires at least an empty definition like this:
virtual ~iFace() {};
Then that member function is not pure virtual (can't be because you gave it a definition) and therefore your class is no longer an interface (it does not only contain pure virtual member functions).
This would imply that if you define a virtual destructor for your interface, then you no longer have an interface (but just some abstract base class). Is this just an abuse of language? Do I understand what is going on?
note: All this came from asking myself "What is an interface?" and then reading this question's answers: How do you declare an interface in C++?
Hope that wasn't too long a walk for too short a ride, but I am determined to completely understand these concepts and their associated vocabulary.
Why Abstract class destructor should be virtual and have a definition?
Calling delete on a polymorphic Base class pointer pointing to a Derived class object & the Base class not having a virtual destructor causes an Undefined Behavior.
So you do need to declare the destructor of the polymorphic Base class as virtual. Once you declare your destructor explicitly virtual, you do need to provide a definition for it. This is because the compiler by default generates(defines) a destructor for every class but if you explicitly declare the destructor then the compiler does not do so and leaves it for you to provide a definition for your own destuctor. It makes sense because the compiler sees explicit declaration as an indication that you want to do some non trivial operations(even if you are not in need of doing so) in the destructor and it provides you the opportunity to do so by forcing you to give the definition.
Myth 1:
There is something called an Interface in C++.
NO
C++ as a language does not provide an Interface
What you refer to as Interface is called an Abstract class in C++. Abstract Classes are used to simulate the behavior of Interface in C++.
What is an Abstract class?
By definition an abstract class should have at least one pure virtual function.
Myth 2:
All functions inside Abstract class need to be pure virtual.
NO
Abstract classes do not require all functions inside them to be pure virtual. An object of an Abstract cannot be created if it has at least one pure virtual function. Though, as you correctly mentioned you can create pointers to it.
Myth 3:
Pure virtual functions cannot have a definition.
NO
It is perfectly valid for Pure virtual functions to have a definition.
Why would I ever need a Pure virtual function with definition?
Code speaks louder then words, So here is a simple example:
Warning: Uncompiled code only for demonstration
class IMyInterface
{
int i;
int j;
public:
virtual void SetMembers(int ii, int jj)=0;
};
/*The pure virtual function cannot be inline in the class definition*/
/*So this has to be here*/
void IMyInterface::SetMembers(int ii, int jj)
{
i = ii;
j = jj;
}
class Myclass: public IMyInterface
{
int k;
int l;
public:
virtual void SetMembers(int ll, int m, int a, int b)
{
k = ll;
l = m;
IMyInterface::SetMembers(a,b);
}
};
int main()
{
MyClass obj;
obj.SetMembers(10,20,30,40);
return 0;
}
C++ doesn't have a native interface entity. Interfaces are implemented as regular classes.
What makes a class an interface in C++ is, therefore, not something that has universal agreement. Personally I consider a class to be an interface if it has no data members, no user-declared constructors and all of its functions are pure virtual - with the possible exception of its destructor - and all of its base classes, if any, are also interfaces. If a class doesn't quite fit all of these properties I might refer to it as a "fat" interface (generally not a compliment!).
If you want to delete dynamically allocated polymorphic classes through a pointer to a base class (such as an "interface" class) then the base class destructor must be declared virtual. This means that it must be a user-declared destructor and not an implicitly declared destructor which would be non-virtual.
Once you declare a destructor explicitly, you must provide an implementation for it. (A base class destructor will always be used when you destroy an instance of any class derived from it whether or not the base class destructor is declared pure virtual, virtual or non-virtual.) This is purely an C++ language implementation detail. It doesn't mean that your base class is any less of an "interface", if you have an interface class then it is very likely that the implementation of the destructor will be empty in any case - you have no members or base classes with members to worry about.
If your interface has at least some pure virtual functions then there is no real merit to marking the destructor as pure, your interface class is already an abstract class. Derived class destructors don't technically override base class destructors so you're not requiring derived classes to provide user-declared destructors or anything like that.
Declaring a destructor as a pure virtual also robs you of the ability to provide the definition of the destructor inline in the class definition, although this is a minor detail.
"An interface is any class with only pure virtual functions"
-- The concept in C++ is called abstract class. An abstract class is a class with at least one pure virtual function. It doesn't require that all of its member functions are pure virtual though. You cannot instantiate any abstract class.
"This would imply that if you define a virtual destructor for your
interface, then you no longer have an interface (but just some
abstract base class). Is this just an abuse of language? Do I
understand what is going on?"
-- On the contrary, you must provide a definition for the destructor even if it is pure virtual because destructors are always called in a down-up manner in inheritance hierarchy.
Standard 12.4:
A destructor can be declared virtual (10.3) or pure virtual (10.4); if any objects of that class or any derived class are created in the program, the destructor shall be defined.
Example:
class A
{
public:
// this is stil a pure virtual function
// when there is a definition
virtual ~A() = 0;
};
class B: public A
{};
int main()
{
// fail to link due to missing definition of A::~A()
B b;
}
OK.
OK; if the member function is not declared virtual in the base class, the one from the base class is called; if the member function is neither defined nor declared pure virtual in the base class, you get an error.
In C++ you don't have interfaces as you have in Java and C#; abstract base classes in C++ combine interfaces and abstract classes as they are present in the latter two languages. A C++ class is abstract if it has at least one pure virtual member function.
Replace interface with abstract class.
Formally you cannot make assumptions on what happens if you delete a derived class from a pointer to a base class if the base class's destructor is not declared virtual.
Given all this, in general your abstract base class will already have some pure virtual member function which ensure that it won't be possible to instantiate it, so the usual way of doing things is to define an inline virtual destructor that does nothing.
I read in my book:
An abstract class is a class that is designed to be specifically used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier (= 0) in the declaration of a virtual member function in the class declaration.
Is it mandatory for an abstract class to have a virtual function? Why?
What is the difference between pure virtual function and virtual function and what is the need of them?
A pure virtual function specifies an interface that must be overridden in a derived class to be able to create objects of the derived class.
A (non-pure) virtual function specifies an interface that can be overridden in a derived class, but the base class provides a default implementation of the interface.
For most practical purposes, yes, an abstract base class must contain at least one virtual function. The whole point of an abstract base class is to specify an interface that's implemented by derived classes. That interface is specified in terms of a number of virtual functions that can be called. Without virtual functions, you haven't specified an interface, which makes it pretty hard for the abstract base class to accomplish much.
If you use an abstract class, that means you don't want to instantiate this class incorrectly. And you must use pure virtual function in that class.But declaring or writing function in class is your choice. You can write the function in derived class too.
The difference is that you cannot instantiate the abstract class - it acts as an interface.
To be abstract a class must have one pure virtual function. Only virtual function can be pure since it could be overriden and thus it's useful for polymorphism. Pure non-virtual function doesn't make sense because it doesn't do anything and couldn't be overriden, so it's useless, and doesn't exist :)
Yes, it must have at least one pure virtual function.
In case all the virtual functions for your base class have an implementation, and you would like to make it abstract nonetheless, you can use a pure virtual destructor:
class MyAbstractClass
{
virtual ~MyAbstractClass() = 0;
virtual void f()
{
IHaveAnImplementation();
SoICannotBePure();
}
};
// The destructor can unfortunately not be defined inline
MyAbstractClass::~MyAbstractClass() {}
This only a conveniance: a pure destructor is not really a pure function since it has a definition. It is only a marker saying that the class cannot be instantiated, although it has no other abstract functions.
pure virtual means the method has no implementation so it forces any non abstract child class to provide that implementation.
In C++, the only way to make a class abstract is to put at least one pure virtual function in it. The compiler won't let you instantiate a class that contains a pure virtual function, because then you'd have an object with a function that has no definition. There are probably cryptic ways to get around this, but this is the standard practice.
The difference between a pure virtual and virtual function is that a pure virtual does not specify the implementation of the method. The =0 syntax tells the compiler that the class is not providing a definition for the function, which makes the function pure virtual and makes the class abstract. Any class deriving from the abstract base class must define the pure virtual function, or else the subclass will be abstract as well.
A "non-pure" virtual function is one which is marked with the virtual keyword, but a definition for the function is supplied in the base class. This means that the base class provides an implementation of the function, which any subclasses can override if desired. The virtual keyword allows polymorphism to work when you're using base class pointers that point to derived class objects.
A virtual function can be overridden in a derived class.
A pure virtual function must be overridden in a derived class.
A class with pure virtual functions cannot be instantiated.
Is it mandatory for an abstract class to have a virtual function? Why?
It depends on the definition you use. The standard use
A class is abstract if it has at least one pure virtual function.
so yes it is mandatory. Informally you may use another definition but then you risk confusion in a C++ context.
What is the difference between pure virtual function and virtual function and what is the need of them?
A pure virtual member:
must be overridden in all non abstract derived class
can be left without definition (but giving a definition is possible, it is even mandatory in the case of a pure virtual destructor).
A pure virtual function is one which must be overridden by any concrete (i.e., non-abstract) derived class. This is indicated in the declaration with the syntax " = 0" in the member function's declaration.
Example:
class AbstractClass {
public:
virtual void AbstractMemberFunction() = 0; // Pure virtual function makes
// this class Abstract class.
virtual void NonAbstractMemberFunction1(); // Virtual function.
void NonAbstractMemberFunction2();
};
In general an abstract class is used to define an implementation and is intended to be inherited from by concrete 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. Otherwise, if any member function of the base class is left undefined, we will create a new abstract class (this could be useful sometimes).