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).
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 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.
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.
I am working on an exercise which asks me to take a base class Rodent and make it a pure abstract class. My understanding of a pure abstract class is that it acts as an interface and only contains pure virtual functions. Although this is an easy exercise I have a problem with the solution provided by the book:
class Rodent
{
public:
virtual ~Rodent() {cout << "Destroy rodent" << endl;}
virtual void run() = 0;
virtual void squeak() = 0;
};
As you can see the author has added a dummy definition for the destructor. Does the adding of this definition not mean that this is an abstract class and not a 'pure' abstract class?
An Abstract class must contain atleast one pure virtual function.
Your class already has two pure virtual functions run() and squeak(), So your class is Abstract because of these two pure virtual functions.
You cannot create any objects of this class.
EDIT:
A pure abstract class, is a class that exclusively has pure virtual functions (and no data).
Since your destructor is not pure virtual your class is not Pure Abstract Class.
A destructor is required for every class by the rules of C++. If you don't provide one, the compiler will generate one for you.
In my opinion this is still a pure abstract class, because the destructor is an exception to the rule.
The virtual keyword means something a bit different for destructors. When a base class's dtors are virtual, it means all dtors in the inheritance hierarchy are called. You can't really override it as such.
Usually you'd expect it to be empty:
class Rodent {
public:
virtual ~Rodent() {}
virtual void run() = 0;
virtual void squeak() = 0;
};
I see very little difference. It is possible that because the empty body is a no-op the compiler can ignore it through some language lawyer statute.
I don't think you'd confuse anyone by calling yours pure virtual.
As far as I understand, the C++ standard does not specify a pure abstract class. The C++0x (n3290) however specifies abstract class.
10.4/2 A class is abstract if it has at least one pure virtual
function.
The pure abstract class is a conventional term and describes an abstract class that;
does not have of data members
does not have of any non-pure virtual functions
does not have of any concrete functions
specified by user.
So, according to this convention, the class Rodent is not a pure abstract class.
Consider implementing your interface like so
class Rodent {
public:
virtual ~Rodent() = 0;
virtual void run() = 0;
virtual void squeak() = 0;
};
inline Rodent::~Rodent() {}
Specifying your destructor as pure virtual and inlining the implementation avoids the following warning in MSVC2010 when exporting subclasses:
warning C4275: non dll-interface class 'A' used as base for dll-interface class 'B'
Yes, it is not a pure class anymore. A pure, abstract class has no functionality in it, it just provides a framework. cout is functionality.