I read on internet that very rarely we will define the function even though it is defined as pure virtual inside the class as below.
class abc
{
public:
virtual void func() = 0;
}
void abc::func()
{
cout << "in abc::func()";
}
I didn't understand the uses of this. On the link http://www.gotw.ca/gotw/031.htm, it got mentioned that we can use this as pure virtual destructor. But I haven't clearly understand. Can any one please let me know what are the uses.
A destructor needs an implementation even if it's pure virtual, because destructors are called automatically and non-virtually (up each base class chain).
Thus if you have a pure virtual destructor you'd better also define it.
Otherwise you will not be able to destroy any object of that class or class derived from that class: a destructor call will be attempted in a destruction, and the linker will complain that it can't find a definition.
By a quirk of syntax that's never been fixed, the definition can't be provided inline in the class definition, but has to be provided separately.
Another use of implemented pure virtual functions is to force subclasses to explicitly ask for the default behaviour. A good example is given in Effective C++ Item 34 (paraphrasing (paracoding?)):
class Airplane
{
public:
virtual void fly() = 0;
};
Airplane::fly()
{
//A default implementation
}
class ModelA : public Airplane
{
public:
virtual void fly() { Airplane::fly(); } //explicitly use the default
};
class ModelB : public Airplane
{
public:
virtual void fly() { Airplane::fly(); } //explicitly use the default
};
class ModelC : public Airplane
{
public:
virtual void fly() { //different implementation }
};
The idea of this is to make it difficult for clients to accidentally inherit default behaviour that they might not want if they thought about it. In more general terms, this idiom is good for avoiding code duplication by factoring out implementations of virtual methods which are not intrinsically default.
There is no rule which prevents you to define pure virtual methods. This can be used to force child classes to provide an implementation, but at the same time gives you the opportunity to provide a convinient implementation as well (doing common tasks).
E.g If xyz derives from abc it can uses abcs function definition in its own:
struct xyz : public abc
{
virtual void func() override
{
abc::func(); // explicitely calling the implementation provided by abc
}
}
Related
My basic understanding is that there is no implementation for a pure virtual function, however, I was told there might be implementation for pure virtual function.
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
Is code above OK?
What's the purpose to make it a pure virtual function with an implementation?
A pure virtual function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions allow it) by using a fully-scoped name (by calling A::f() in your example - if A::f() were public or protected). Something like:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designer wants that sort-of-default behavior be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.
Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).
To be clear, you are misunderstanding what = 0; after a virtual function means.
= 0 means derived classes must provide an implementation, not that the base class can not provide an implementation.
In practice, when you mark a virtual function as pure (=0), there is very little point in providing a definition, because it will never be called unless someone explicitly does so via Base::Function(...) or if the Base class constructor calls the virtual function in question.
The advantage of it is that it forces derived types to still override the method but also provides a default or additive implementation.
If you have code that should be executed by the deriving class, but you don't want it to be executed directly -- and you want to force it to be overriden.
Your code is correct, although all in all this isn't an often used feature, and usually only seen when trying to define a pure virtual destructor -- in that case you must provide an implementation. The funny thing is that once you derive from that class you don't need to override the destructor.
Hence the one sensible usage of pure virtual functions is specifying a pure virtual destructor as a "non-final" keyword.
The following code is surprisingly correct:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
You'd have to give a body to a pure virtual destructor, for example :)
Read: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
(Link broken, use archive)
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
Yes this is correct. In your example, classes that derive from A inherit both the interface f() and a default implementation. But you force derived classes to implement the method f() (even if it is only to call the default implementation provided by A).
Scott Meyers discusses this in Effective C++ (2nd Edition) Item #36 Differentiate between inheritance of interface and inheritance of implementation. The item number may have changed in the latest edition.
The 'virtual void foo() =0;' syntax does not mean you can't implement foo() in current class, you can. It also does not mean you must implement it in derived classes.
Before you slap me, let's observe the Diamond Problem:
(Implicit code, mind you).
class A
{
public:
virtual void foo()=0;
virtual void bar();
}
class B : public virtual A
{
public:
void foo() { bar(); }
}
class C : public virtual A
{
public:
void bar();
}
class D : public B, public C
{}
int main(int argc, const char* argv[])
{
A* obj = new D();
**obj->foo();**
return 0;
}
Now, the obj->foo() invocation will result in B::foo() and then C::bar().
You see... pure virtual methods do not have to be implemented in derived classes (foo() has no implementation in class C - compiler will compile)
In C++ there are a lot of loopholes.
Hope I could help :-)
If I ask you what's the sound of an animal, the correct response is to ask which animal, that's exactly the purpose of pure virtual functions, or abstract function is when you cannot provide an implementation to your function in the base class (Animal) but each animal has its own sound.
class Animal
{
public:
virtual void sound() = 0;
}
class Dog : public Animal
{
public:
void sound()
{
std::cout << "Meo Meo";
}
}
One important use-case of having a pure virtual method with an implementation body, is when you want to have an abstract class, but you do not have any proper methods in the class to make it pure virtual. In this case, you can make the destructor of the class pure virtual and put your desired implementation (even an empty body) for that. As an example:
class Foo
{
virtual ~Foo() = 0;
void bar1() {}
void bar2(int x) {}
// other methods
};
Foo::~Foo()
{
}
This technique, makes the Foo class abstract and as a result impossible to instantiate the class directly. At the same time you have not added an additional pure virtual method to make the Foo class abstract.
I created Interfaces (abstract classes) that expends other Interfaces in C++ and I tried to implement them but errors occur when I compile.
Here are the errors:
main.cpp: In function 'int main()':
main.cpp:36:38: error: cannot allocate an object of abstract type 'Subclass'
Subclass * subObj = new Subclass();
^
Subclass.h:13:7: note: because the following virtual functions are pure within 'Subclass':
class Subclass : SubInterface {
^
SuperInterface.h:13:18: note: virtual void SuperInterface::doSomething()
virtual void doSomething()=0;
Here are my sources:
#include <iostream>
class SuperInterface {
public:
virtual void doSomething() = 0;
protected:
int someValue;
};
class SubInterface : public SuperInterface {
public:
virtual void doSomethingElseThatHasNothingToDoWithTheOtherMethod() = 0;
protected:
int anotherValue;
};
class Superclass : public SuperInterface {
public:
Superclass() {}
virtual ~Superclass() {}
void doSomething() {std::cout << "hello stackoverflow!";}
};
class Subclass : public SubInterface {
public:
Subclass() {}
virtual ~Subclass() {}
void doSomethingElseThatHasNothingToDoWithTheOtherMethod() {std::cout << "goodbye stackoverflow!";}
};
int main(void)
{
Superclass * superObj = new Superclass();
Subclass * subObj = new Subclass();
}
Here's what I want:
I want my implementation to be aware and so have the same behaviour as of already overriden methods (e.g subObj->doSomething() method works without the need to implement it again). Can anyone tell me what I should do to make that happen if it's even possible? Thanks.
No, you can't do what you want through simple inheritance. At no point does Subclass inherit, or provide, an implementation of doSomething(), so you can't call subObj->doSomething() as you desire. You must honour the interface contract of subInterface.
You could inherit Subclass from Superclass and Subinterface, and just implement doSomething() as a kind of proxy, Superclass::doSomething(). You still need an implementation but you don't have to 're-implement' it.
You're getting the error because you're trying to create an object of an abstract class.
Your Subclass is an abstract class because of this line void doSomethingElse()=0;.
If a class has one pure virtual function, it will be an abstract class. You can't create an object of an abstract class, you can only have a reference or a pointer to it.
To get rid of the error, the declaration of doSomethingElse in Subclass should be
void doSomethingElse();
Instead of void doSomethingElse()=0;
Also I don't see why you need two interfaces. You could derive Subclass from the SuperInterface, as it is basically just the same as SubInterface
To be honest, I am not entirely sure what your design wants to express, but there are at least two technical errors here:
1.) You use private inheritance in all cases, so you do not actually deal with "interfaces" at all. Public inheritance is achieved like this:
class SubInterface : public SuperInterface
2.) You use =0 for a function you apparently want to implement.
This will fix the compiler errors, but the design is still questionable. Considering the motivation you gave at the end of your question, I recommend composition rather than (public) inheritance. In C++, to share functionality is best expressed with composition. To put it very brief, encapsulate the commonly used functionality in a separate class and equip the other classes with an object of it.
class CommonFunctionality
{
//...
public:
void doSomething();
void doSomethingElse();
};
class SuperClass
{
//...
private:
CommonFunctionality m_functionality;
};
class SubClass : public SuperClass
{
//...
private:
CommonFunctionality m_functionality;
};
In fact, perhaps you don't even need to create a class for CommonFunctionality. Perhaps simple free-standing functions would do. Programmers with a Java background (and your code looks a bit like it) tend to put too stuff into classes than what is necessary in C++.
Your class 'Subclass' should override 2 pure virtual methods, so:
class Subclass : SubInterface {
public:
Subclass();
virtual ~Subclass();
void doSomethingElse() override;
void doSomething() override;
};
by not doing so or stating
void doSomethingElse()=0;
class Subclass becomes abstract too, which cannot be instantiated. You could havea look at :http://www.parashift.com/c++-faq-lite/pure-virtual-fns.html
Here's what I want: I want my implementation to be aware and so have
the same behaviour as of already overriden methods (e.g
subObj->doSomething() method works without the need to implement it
again). Can anyone tell me what I should do to make that happen if
it's even possible!!?? Thanks.
--> maybe declare the methods virtual not pure virtual
There are 2 problems, which are clearly stated by compiler:
Problem 1
SubInterface::doSomethingElse()() in Subclass is declared as pure virtual, disregarding that you trying to define it in source file (I'm pretty sure, that this is a copy-paste kind of errors).
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
void doSomethingElse() = 0; // still pure?
};
Solution is obvious:
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
virtual void doSomethingElse() override
{
}
};
(here using C++11 override specifier, so compiler will check correctness of overriding; it is not obligatory)
Problem 2
doSomething() is not even tried to be overriden, neither in SuperInterface, nor in Subclass, so it stays pure virtual. Although doSomething() is overriden in Superclass, Subclass has no idea about existance of Superclass.
Solution: override doSomething() either in SuperInterface, or in Subclass, or in any of children of Subclass (don't have them yet). For example, overriding in Subclass:
class Subclass : SubInterface
{
public:
Subclass();
virtual ~Subclass();
virtual void doSomething() override
{
}
virtual void doSomethingElse() override
{
}
};
Other issues:
You are inheriting without visibility specifier, i.e. privately. Use public inheritance until you really need something else:
class Derved : public Base {};
Your source files have .c extension, but containing C++ code. This can confuse some compilers if you do not state programming language explicitly via command line arguments. By convention, most programmers use .cpp extension, and most compilers treat such files as C++ source files.
The benefit of defining common virtual functions in the base class is that we don't have to redefine them in the derived classes then.
Even if we define pure virtual functions in the base class itself, we'll still have to define them in the derived classes too.
#include <iostream>
using namespace std;
class speciesFamily
{
public:
virtual void numberOfLegs () = 0;
};
void speciesFamily :: numberOfLegs ()
{
cout << "\nFour";
}
class catFamily : public speciesFamily
{
public:
void numberOfLegs ()
{
speciesFamily :: numberOfLegs ();
}
};
This may look fancy for sure, but are there any situations when it is beneficial to define a pure virtual function in the base class itself?
Two things:
First off, there's one border-line scenario which is commonly cited: Suppose you want an abstract base class, but you have no virtual functions to put into it. That means you have no functions to make pure-virtual. Now there's one way around: Since you always need a virtual destructor, you can make that one pure. But you also need an implementation, so that's your canditate:
struct EmptyAbstract
{
virtual ~EmptyAbstract() = 0; // force class to be abstract
};
EmptyAbstract::~EmptyAbstract() { } // but still make d'tor callable
This may help you minimize the implementation size of the abstract class. It's a micro-opimization somehow, but if it fits semantically, then it's good to have this option.
The second point is that you can always call base class functions from derived classes, so you may just want to have a "common" feature set, despite not wanting any abstract instances. Again, in come pure-virtual defined functions:
struct Base
{
virtual void foo() = 0;
};
struct Derived : Base
{
virtual void foo()
{
Base::foo(); // call common features
// do other stuff
}
};
void Base::foo() { /* common features here */ }
are there any situations when it is beneficial to define a pure virtual function in the base class itself?
Yes - if the function in question is the pure virtual destructor, it must also be defined by the base class.
A base-class with only pure virtual functions are what languages like Java would call an interface. It simply describes what functions are available, nothing else.
It can be beneficial when there is no reasonable implementation of pure virtual function can be in base class. In this case pure virtual functions are implemented in derived classes.
Can we write abstract keyword in C++ class?
#define abstract
No.
Pure virtual functions, in C++, are declared as:
class X
{
public:
virtual void foo() = 0;
};
Any class having at least one of them is considered abstract.
No, C++ has no keyword abstract. However, you can write pure virtual functions; that's the C++ way of expressing abstract classes.
It is a keyword introduced as part of the C++/CLI language spefication for the .NET framework.
no, you need to have at least one pure virtual function in a class to be abstract.
Here is a good reference cplusplus.com
As others point out, if you add a pure virtual function, the class becomes abstract.
However, if you want to implement an abstract base class with no pure virtual members, I find it useful to make the constructor protected. This way, you force the user to subclass the ABC to use it.
Example:
class Base
{
protected:
Base()
{
}
public:
void foo()
{
}
void bar()
{
}
};
class Child : public Base
{
public:
Child()
{
}
};
actually keyword abstract exists in C++ (VS2010 at least) and I found it can be used to declare a class/struct as non-instantiated.
struct X abstract {
static int a;
static void foX(){};
};
int X::a = 0;
struct Y abstract : X { // something static
};
struct Z : X { // regular class
};
int main() {
X::foX();
Z Zobj;
X Xobj; // error C3622
}
MSDN: https://msdn.microsoft.com/en-us/library/b0z6b513%28v=vs.110%29.aspx
There is no keyword 'abstract' but a pure virtual function turns a class in to abstract class which one can extend and re use as an interface.
No, you can't use abstract as a keyword because there is no such keyword available in C++.
If you want to declare a C++ class as abstract, you can declare at least one function as a pure virtual function.
But in derived class you must provide a definition otherwise its give compilation error.
Example:
class A
{
public:
virtual void sum () = 0;
};
note:
You can used abstract as a variable name, class name because, as I told you, abstract is not a keyword in C++.
No, C++ has no keyword abstract. However, you can write pure virtual functions; that's the C++ way of expressing abstract classes. It is a keyword introduced as part of the C++/CLI language spefication for the .NET framework. You need to have at least one pure virtual function in a class to be abstract.
class SomeClass {
public:
virtual void pure_virtual() = 0; // a pure virtual function
};
Most C++ compilers do not have an abstract keyword.
A Cheap Abstract Keyword
Although you could define a macro with that name like so:
#define abstract
class foo abstract { ... };
It would have absolutely no effect on the class, however, if any variable, function, anything is named "abstract", that #define is not going to make your code happy.
Create an Abstract Class
As mentioned by others, you can force a class to be abstract by creating a Pure Virtual function and set it to 0 like so:
class foo
{
virtual void func() = 0;
};
foo::func() { /* some default code [not required] */ }
Pro: Since even a pure virtual function can have a body, you can make a class abstract even though the very function you defined as abstract (pure virtual) is defined. However, contrary to the other virtual functions, having a body is not required of pure virtual functions.
Con: You are forced to create at least one pure virtual function and that forces all derived classes to define that function to not be viewed as abstract. If you anyway have such a function, then great! But often, this is not the case.
The Correct Way
There is actually an astute way of creating an abstract class which is not well known. You still have to create a pure virtual function... and the fact is that the destructor can be a pure virtual function! There is ALWAYS a destructor in a class that uses the virtual keyword, so there is no hesitation here.
class foo {
virtual ~foo() = 0;
};
foo * f(new foo); // this fails, foo is abstract
The classes that derive from foo must now declare an explicit destructor (newer compilers properly create one implicitly, but it would still be a pure virtual function) which is not pure virtual like so:
class bar : public foo {
virtual ~bar() override {}
};
Note that we do not have an abstract keyword, but we do have an override keyword, which is super useful so when a function signature changes, you cannot compile until all the classes that derive from your base class have their virtual functions updated accordingly.
Effect of the Default Destructor
An interesting aspect to using the destructor as the pure virtual function is that derived classes automatically get a destructor (if you don't define one) and means your derived classes are automatically non-abstract (assuming only the destructor is a pure virtual in the base class).
In other words, you could declare bar with:
class bar : public foo {
void some_function();
};
and it automatically is not abstract because the default destructor is not abstract as it will more or less look like this:
virtual ~bar() override {}
if you don't define it yourself.
In other words, if you want to define another layer which still is abstract (i.e. if you want new bar to fail to compile), then you must declare your own destructor and mark it as a pure virtual:
class bar : public foo {
virtual ~bar() override = 0;
void some_function();
};
bar::~bar() {}
(the {} and = 0 can't be used together so you have to declare the destructor body separately.)
Abstract keyword presents in java, similar abstraction we can achieve in C++ by using pure virtual function.
My basic understanding is that there is no implementation for a pure virtual function, however, I was told there might be implementation for pure virtual function.
class A {
public:
virtual void f() = 0;
};
void A::f() {
cout<<"Test"<<endl;
}
Is code above OK?
What's the purpose to make it a pure virtual function with an implementation?
A pure virtual function must be implemented in a derived type that will be directly instantiated, however the base type can still define an implementation. A derived class can explicitly call the base class implementation (if access permissions allow it) by using a fully-scoped name (by calling A::f() in your example - if A::f() were public or protected). Something like:
class B : public A {
virtual void f() {
// class B doesn't have anything special to do for f()
// so we'll call A's
// note that A's declaration of f() would have to be public
// or protected to avoid a compile time problem
A::f();
}
};
The use case I can think of off the top of my head is when there's a more-or-less reasonable default behavior, but the class designer wants that sort-of-default behavior be invoked only explicitly. It can also be the case what you want derived classes to always perform their own work but also be able to call a common set of functionality.
Note that even though it's permitted by the language, it's not something that I see commonly used (and the fact that it can be done seems to surprise most C++ programmers, even experienced ones).
To be clear, you are misunderstanding what = 0; after a virtual function means.
= 0 means derived classes must provide an implementation, not that the base class can not provide an implementation.
In practice, when you mark a virtual function as pure (=0), there is very little point in providing a definition, because it will never be called unless someone explicitly does so via Base::Function(...) or if the Base class constructor calls the virtual function in question.
The advantage of it is that it forces derived types to still override the method but also provides a default or additive implementation.
If you have code that should be executed by the deriving class, but you don't want it to be executed directly -- and you want to force it to be overriden.
Your code is correct, although all in all this isn't an often used feature, and usually only seen when trying to define a pure virtual destructor -- in that case you must provide an implementation. The funny thing is that once you derive from that class you don't need to override the destructor.
Hence the one sensible usage of pure virtual functions is specifying a pure virtual destructor as a "non-final" keyword.
The following code is surprisingly correct:
class Base {
public:
virtual ~Base() = 0;
};
Base::~Base() {}
class Derived : public Base {};
int main() {
// Base b; -- compile error
Derived d;
}
You'd have to give a body to a pure virtual destructor, for example :)
Read: http://cplusplus.co.il/2009/08/22/pure-virtual-destructor/
(Link broken, use archive)
Pure virtual functions with or without a body simply mean that the derived types must provide their own implementation.
Pure virtual function bodies in the base class are useful if your derived classes wants to call your base class implementation.
Yes this is correct. In your example, classes that derive from A inherit both the interface f() and a default implementation. But you force derived classes to implement the method f() (even if it is only to call the default implementation provided by A).
Scott Meyers discusses this in Effective C++ (2nd Edition) Item #36 Differentiate between inheritance of interface and inheritance of implementation. The item number may have changed in the latest edition.
The 'virtual void foo() =0;' syntax does not mean you can't implement foo() in current class, you can. It also does not mean you must implement it in derived classes.
Before you slap me, let's observe the Diamond Problem:
(Implicit code, mind you).
class A
{
public:
virtual void foo()=0;
virtual void bar();
}
class B : public virtual A
{
public:
void foo() { bar(); }
}
class C : public virtual A
{
public:
void bar();
}
class D : public B, public C
{}
int main(int argc, const char* argv[])
{
A* obj = new D();
**obj->foo();**
return 0;
}
Now, the obj->foo() invocation will result in B::foo() and then C::bar().
You see... pure virtual methods do not have to be implemented in derived classes (foo() has no implementation in class C - compiler will compile)
In C++ there are a lot of loopholes.
Hope I could help :-)
If I ask you what's the sound of an animal, the correct response is to ask which animal, that's exactly the purpose of pure virtual functions, or abstract function is when you cannot provide an implementation to your function in the base class (Animal) but each animal has its own sound.
class Animal
{
public:
virtual void sound() = 0;
}
class Dog : public Animal
{
public:
void sound()
{
std::cout << "Meo Meo";
}
}
One important use-case of having a pure virtual method with an implementation body, is when you want to have an abstract class, but you do not have any proper methods in the class to make it pure virtual. In this case, you can make the destructor of the class pure virtual and put your desired implementation (even an empty body) for that. As an example:
class Foo
{
virtual ~Foo() = 0;
void bar1() {}
void bar2(int x) {}
// other methods
};
Foo::~Foo()
{
}
This technique, makes the Foo class abstract and as a result impossible to instantiate the class directly. At the same time you have not added an additional pure virtual method to make the Foo class abstract.