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.
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.
Pure virtual functions are a must-have property for abstract base classes. So no implementations should be made, which is very intuitive to understand. But Recently I came to know that pure virtual functions can still be defined later and be invoked statically(not by object instances). I can't think up a reason for this. If one virtual function is defined as pure, then what's the reason to implement it?
class A{
public:
...
virtual void interface() = 0; //Pure Virtual functions
...
}
void A::interface() //Implementation
{
cout<<"This the implementation for A interface";
}
I am curious about the logic behind this. Why is c++ designed like this way?
It might make sense to have a "default" implementation, which concrete classes can use if it's useful to them. They still need to override it, but can call the base-class version non-virtually:
struct B : A {
void interface() {
A::interface(); // call the default implementation
// and maybe do some B-specific things too
}
};
I can't think up a reason for this. If one virtual function is defined as pure, then what's the reason to implement it?
The purpose of a pure virtual function is not to prohibit definitions. It is to mark the class as uninstantiable.
Providing a definition may be useful for deriving classes:
struct A
{
virtual void foo() = 0;
};
void A::foo()
{
/* some common logic here */
}
struct B : A
{
virtual void foo() overrides
{
bar();
A::foo();
}
void bar();
};
struct C : A
{
virtual void foo() overrides
{
baz();
A::foo();
}
void baz();
};
A pure virtual function simply means that the function must be overidden by all derived classes it does not mean that the function cannot/should not have a implementation of its own. Two most obvious cases for such a pure virtual function having implementation are:
A Derived class implementation can call Base class implementation
Sometimes you would want a base class to be made abstract but there is no method which you can mark as pure virtual in such a case a destructor is most obvious choice but in such a destructor still needs a implementation.
interface() = 0 means derived classes must provide an implementation, so the definition effects derived classes, but the base class is permitted to have an implementation of the method so that derived classes can always call base::interface().
You apparently completely misunderstood the meaning of the term "statically" in this context.
Yes, pure virtual functions can still have bodies, i.e. they can still be defined.
And no, you cannot invoke such function "without an object instance", as you seem to incorrectly believe. A pure virtual function with a body is still a non-static member function. It still requires an object instance to be invoked.
When someone says that such function can be invoked "statically", it means that it can be called directly, without using virtual dispatch mechanism. Function calls that go through virtual dispatch are sometimes called "virtual calls" or "dynamic calls", while direct function calls are sometimes called "static calls". The term "static" in this context assumes a completely different meaning, not connected in any way to static member functions.
In C++ language a direct non-virtual (i.e. "static") call can be performed explicitly by specifying a qualified member name in the call. For example, if class B derives from your class A, then inside some method B::foo() you can use the following syntax
void B::foo() {
A::interface(); // <- qualified method name
}
which performs a direct call to the implementation of A::interface() you provided. For an object b of type B the same kind of call can be performed as
B b;
b.A::interface(); // <- qualified method name
In both cases the call is performed for a specific object (*this in the first example, and b in the second).
Pretty much the same thing happens implicitly when destructors of derived classes call destructors of base class, which is why you will often encounter this situation with pure virtual destructors (i.e. they are declared as pure virtual, yet have a body).
Scott said on Effective C++, 3rd Edition, pg. 43 that to make an abstract class, we just need to give it a pure virtual destructor:
class AWOV { // AWOV = "Abstract w/o Virtuals"
public:
virtual ~AWOV() = 0; // declare pure virtual destructor
};
Then, he went on said that there is one twist: we must provide a definition for the pure virtual destructor:
AWOV::~AWOW() {} // definition of pure virtual dtor
My question is, by specifiying = 0, for pure virtual functions, we are saying that the function cannot have any definition for the class where this pure virtual function is declared.
Why is it OK to provide a definition (even it is empty) for the pure virtual destructor here?
"we are saying that the function cannot have any definition for the class where this pure virtual function is declared."
That's not what pure virtual means. Pure virtual only means that the containing class cannot be instantiated (is abstract), so it has to be subclassed, and subclasses must override the method. E.g.,
struct A {
virtual ~A() = 0;
};
A::~A() {}
struct B : A {};
int main()
{
A a; // error
B b; // ok
}
Here, the B destructor is implicitly defined. If it was another method that is pure virtual, you'd have to explicitly override it:
struct A {
virtual void foo() = 0;
};
void A::foo() {}
struct B : A {};
int main()
{
B b; // error
}
Providing a definition for a pure virtual method is desirable when the base class must be abstract but still provide some default behavior.
In the specific case of a destructor, it has to be provided because it will be called automatically when subclass instances are destroyed. A program that tries to instantiate a subclass of a class with a pure virtual destructor without a definition will not pass the linker.
Making it pure forces derived (non-abstract) classes to implement their own.
Providing an implementation allows derived classes to invoke base class behavior (which destructors do by default).
There are 2 cases.
Pure virtual destructor
This case is specifically treated by the standard.
12.4 Destructors [class.dtor]
9) 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. If a class has a base class with a
virtual destructor, its destructor (whether user- or implicitly-declared) is virtual.
The case of the destructor is different because all destructors are called in an inheritance hierearchy (assuming correct deletion) in reverse order of construction, even if not explicitly. So the base class destructor is called when the object gets deleted - that's why it needs an implementation.
Pure virtual method
These differ from destructors in that they're not required to be implemented, nor do they need an implementation. The difference for the missing requirement is that when a Derived::foo() gets called, it doesn't automatically call Base::foo() (not that it could, since it can or can not be implemented).
Why you would want to implement a pure virtual method depends on the case. I look at the pure specifier as a hint to the programmer, as opposed to related to the logic. It tells you - the programmer - that you should implement that method. It doesn't really matter if the base class has an implementation or not.
by specifiying = 0, for pure virtual functions, we are saying that the function cannot have any definition for the class where this pure virtual function is declared.
Not really. You're saying derived non-abstract classes have to override that function. This doesn't prevent you from implementing it yourself.
This is not necessary for all pure virtual functions. Not at all.
This way, the derived classes will still be forced to override the implementation, but there will be a default implementation in the base class, in case you need to call it. And that's the case here - because you're dealing with a destructor: when a derived object is being destroyed, its destructor is called and its base classes destructors are called as well. That's why you need an implementation for A::~A.
By making a function pure virtual we force the user of the class to replace the function with another in the derived class.
The base class function can still be called with BaseClass::myfunction(...)
Now the base class might want to provide some core functionality that the derived class may use if it chooses to do so.
Correct answer:
Suppose there are 2 pure virtual functions in class. Now assume that both have implementation. The reason for providing implementation for PVF is that the Base class method can act as default behavior if Base class is derived by child by implementing these PVF methods(to make class as concrete)
Is it essential to have a definition for a virtual function?
Consider this sample program below:
#include <iostream>
using namespace std;
class base
{
public:
void virtual virtualfunc();
};
class derived : public base
{
public:
void virtualfunc()
{
cout << "vf in derived class\n";
}
};
int main()
{
derived d;
return 0;
}
This gives the link-error:
In function base::base():: undefined reference to vtable for base
I do not have the definition for the virtual function in base class. Why is this error occurring even though I have not explicitly invoked the virtual function?
The interesting thing which I find is that if I do not instantiate an object of class derived, the link error is no longer there. Why is this? What has instantiation got to do with the above link error?
The ISO C++ Standard specifies that all virtual methods of a class that are not pure-virtual must be defined.
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.
If you are using gcc, You might get some weird errors if you fail to follow this standard specification. 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.
You need to provide an implementation of a virtual function ( with its default behaviour ) unless you define the function to be "pure virtual".
So your example could be:
class base
{
public:
void virtual virtualfunc() {} //intentionally do nothing;
};
or
class base
{
public:
void virtual virtualfunc()=0; //pure virtual;
};
You either need to provide a definition, or mark it as abstract/pure-vitual.
void virtual virtualfunc() = 0;
In response to the error about the vtable: the virtual command in this case tells c++ to produce a virtual table of the methods in the base class. In this way when you use polymorphism, C++ is able to replace the base class virtual methods with the methods from the derived class with the same name during run time. This error is telling the user that this replacement is not possible. To fix this error, you will either need to implement the method or set it as pure virtual by adding "=0" at the end of the definition.
In response to the edits: The reason you are not getting an error when you instantiate the object as a base class is because the base class does not need to access the virtual table. On the other hand if you actually try to use this method, you should get an error since no implementation exists. In other words even though you can instantiate an object of the base class its not a complete class.
Yes you would need a body, but perhaps what you are referring to is called a pure virtual functions, which would not need a definition in the base class.
The syntax to define those is as follows:
void virtual virtualfunc() = 0;
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).