Here is an interview question :
How can we implement an abstract base class without using pure virtual functions.
What we can do so that we cannot create any object of a class because in that case we can say our class is an abstract base class.
At first I thought of using an virtual destructor but I am not sure about this solution because of virtual keyword. Can you please help?
You ask two questions, which we will answer in turn:
How can we implement an abstract base class without using pure virtual functions?
It is impossible, per the definition of an abstract class: "A class is abstract if it has at least one pure virtual function" (C++11 ยง10.4/2). Therefore, in order to be abstract, a class must declare a pure virtual function or it must inherit one from another class from which it derives.
What we can do so that we cannot create any object of a class?
This question can be interpreted in a number of different ways, each of which has a different solution.
Taken literally, the question asks for a type of which no instance may be created. A class with no defined constructors cannot be constructed.
To accomplish this, one should declare (but not define) a default constructor and copy constructor for the class. If one is using a compiler with support for C++11's deleted special member functions, they should be declared as deleted.
Taken in the context of the first question, it seems more likely that the intent is to define a class that can only be instantiated as a base class subobject of another class.
This can be accomplished by declaring all constructors as protected, not providing any static factory member function that creates instances of the class, and by not befriending any other classes or functions.
A virtual destrutor won't do the required job.You can do either of the following:
Declare a pure virtual destructor with a definition.
Make constructor of the base class protected.
for more clear explanation refer to Making a class abstract without any pure virtual methods.
Related
This question already has answers here:
object of abstract class type "Connection" is not allowed
(3 answers)
Closed 8 years ago.
I have problem using class base with pure virtual method.
The method should be virtual.
I get this error:
Error: object of abstract class type "Membro" is not allowed: function "Membro::mensalidade" is a pure virtual function
Anyone can help?
Thanks!
The problem is clear from the error message: you may not instantiate an object of an abstract class.
However it seems that there is no need to create an object of the abstract class in the function you showed. As I have understood the function searches an object with the given string bi. You could use a lambda expression in some search method.
That is the problem is that the design of the function is incorrect.
To get more exact answer you should show the function and what is the type of membros.
Just like the error says Membro::mensalidade is a pure virtual function. This means you cannot use Membro directly but you have to implement it in a subclass and reimplement at least all the pure virtual methods.
If a class contains at least one pure virtual function, then that class is abstract. That means you cannot create object of that class. Abstract classes serves as interface classes to more derived class.
However, you can define that pure virtual function. But this feature is of limited use except to impress your fellow workers.
You cannot instantiate an abstract class.
Any class is abstract if it contains at least one one pure-virtual method (e.g. anything with =0; at the end of the function signature).
You must instantiate a class derived from the abstract class (which must implement the pure-virtual function(s) to not be abstract itself) instead and return a pointer to that. The pointer's type can be the type of the abstract class, and the object that it points to must be a subclass of the abstract class, allowing you to access the derived classes polymorphically.
You have to imeplement the virtual method in a derived class. It is pure virtual to make sure that you implement it when deriving from the class. It also means that there is no default implementaion of that method.
This kind of class has a name they are called Abstract Classes. or Interfaces.
I am looking at the following:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fcplr142.htm
and it says an abstract class in C++ contains a pure virtual function. However, surely this does not mean to create an abstract class all I do is insert a pure virtual function? Couldn't I have the situation where I have a concrete class which doesn't provide an implementation for one particular function and therefore makes it abstract, forcing derived classes to provide the implementation? This wouldn't make the class abstract though?
So how do I differentiate between "this is an abstract class" and "this is a concrete class with one pure virtual function"?
A class is extactly then abstract when it has one or more pure virtual function. If you write a (base) class, wich has all functions implemented, and thus can be instantiated, but it misses a vital function, then it is simply wrong design of your class.
Your base class wouldn't be complete in this case and the pure virtual uninmplemented function should be added, which makes it an abstract class then.
If you have a derived class, which derives from an abstract class, and doesn't implement all functions from the base class, then it is in turn also abstract. In this case, it wouldn't need a pure virtual function itself, because it is abstract by inheritance.
There is no abstract keyword in C++, like in Java to indicate that a class is abstract.
As already stated above, an abstract class in C++ is, by definition, a class which has at least one pure virtual function. The class being abstract means that you can't make instances of it (only of "concrete" classes derived from it), which protects you from calling the "unexistent" pure virtual functions (although technically you can still call them from base class constructor/destructor and get a nasty runtime crash).
There are no explicit "interface" kind of classes in C++, so you are free to provide implementation for some functions in any classes as you wish, regardless of whether the class is already abstract due to some other function being pure virtual.
On a side note, I'd still like to point out one way to make your class abstract without actually making any "real" methods pure virtual. It is enough to make the class destructor pure virtual (note that it is generally a good idea for the destructor of any polymorphic class to be virtual anyway). A minor gotcha here is that in this particular case (only for destructor), you will still have to provide an implementation for it for the linker to be happy. It may look like this:
class A // abstract class
{
public:
virtual ~A() = 0 {} // destructor is pure virtual, but still needs a body
};
class B : public A {}; // concrete class deriving from an abstract class
Also note that in this particular case, class B does not have to explicitly implement its own destructor to become concrete, so, if you'd like it to be abstract too, you'll have to repeat the same trick again (or add some other pure virtual methods to B).
I need to understand these statements:
virtual string FOOy() = 0;
virtual string FOOx( bool FOOBAR ) = 0;
I am not sure if the function being virtual has anything to do with it...
Although your testcase is woefully incomplete, from the presence of the keyword virtual it looks like this is inside a class definition.
In such a context, = 0 is not an assignment at all, but a piece of confusing syntax that marks the virtual member function as being "pure". A pure virtual member function may have an implementation (defined elsewhere), but one is optional and the function's very existence prohibits the class from being instantiated.
That is, a class with pure virtual member functions may be called "abstract".
Your peer-reviewed C++ book covers the topic in much greater detail.
It means that the method is pure, or abstract. It means that the method is meant to be declared by extending classes (thanks for clarifying this--see comments below).
The = 0 syntax is how you declare a pure virtual function in C++. A pure virtual has no implementation in the class declaring it -- any subclass must implement the function in order to be instantiable.
http://www2.research.att.com/~bs/glossary.html#Gpure-virtual-function
That makes the function a pure virtual function. This means that the class that declares the function is abstract, and subclasses must provide an implementation for this function.
By adding the = 0 you are declaring the virtual function to be pure virtual function. This means that derived classes must implement the method before they can be instantiated. Normally the base class does not have implementation.
This is also called an abstract function in other languages, such as Java and C#.
It simply means, that the implementor (Original writer) of the class in which FOOx and FOOy intended it to be used as an interfaces to its Derived Classes.
And these being virtual means, it will be possible that the derived class' implementation will be used, using the base class' pointer. So its being usable as an interface becomes possible by declaring them as virtual.
And finally, answering your question. Value-assignment, specifically assigning 0 to a function means, explicitly saying, that function doesn't has any definition. (Though you can specify a definition for it, but it will need to be called explicitly by the derived classes)
Say I have CFooer and it implements method void foo().
I then have ISomething that has virtual void foo() = 0.
I now create a class:
class CSuperFoo : public CBase, public CFooer, public ISomething
{
};
When I instance CSuperFoo, will I get a cannot instance abstract class error, or would this use CFooer's implementation to satisfy ISomething. If this does not work, why doesn't it?
Thanks
You will have to provide an implementation in the Derived class CSuperFoo to be able to create objects of it, otherwise it will be an Abstract class.
The method foo() from the Base class ISomething needs to be overridden in the deriving class CSuperFoo explicitly because compiler cannot see any relation between method from class CFooer and ISomething::foo() as there is no relation between CFooer & ISomething, SO it demands the specific method being implemented in the derived class so that it is not an Abstract class anymore.
Does'nt work on Ideone.
If CFooer virtually inherits from ISomething I believe it should work ok (I didn't test it). If it doesn't inherit virtually then it will be treated as two distinct methods, and the abstract one will need to be overridden.
Typically in C++ one doesn't use inheritance to implement an interface though and see this code seems like a code smell at first glance. There might be a better, more C++ idiomatic approach if you gave us more details.
Short answer: No you cannot instantiate it.
Explanation:
First you cannot instantiate a abstract class. An abstract class is a class that has a pure virtual function. You know that. Now any class that derives from this abstract class is still abstract until it implements those pure virtual functions. So if I SuperFoo inherits from ISomething, then until it implements the pure virtual functions declared in ISomething, SuperFoo will stay abstract. Now you may think that well, CFooer implements that pure virtual function declared in ISomething, and hence SuperFoo implements it. But if you think that then your forgetting something, namely function hiding, see, now SuperFoo definition of the pure virtual function gets hidden from the function prototype in ISomething, hence the pure virtual function needs to be defined. All of this assumes CFooer inherits from ISomething, since it has the same function definition and if not then your doing it wrong, actually you probably should even be in this situation.
One more thing to add is that if CFooer does inherit from ISomething, as it probably should, then there is no need for ISomething to be part of CSuperFoo. You can simply declare the defined function in CFooer as virtual and then again implement it in SuperFoo. There are also more problems that are possible depending on the minor detail of your code, such are the need for virtual inheritance.
As per the C++ FAQ this is "legal, but not moral".
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.8
Essentially, you will "hide" the CFooer::foo() by implementing a virtual or non-virtual method with the same name foo in the derived class.
There are different cases to consider here. The first thing is what is the exact meaning of your sentence: CFooer implements method void foo(). If the meaning of that sentence is that there is a function with the same signature of the pure abstract function in ISomething, then that is not implementing the function on the interface.
If CFooer, on the other hand derives from ISomething interface, then CFooer::foo does implement the function and provides a final overrider. The problem is that because CSuperFoo derives from both CFooer and ISomething, it contains two different subobjects of type ISomething, and CFooer is only providing a final-overrider for one of them, and CSuperFooer is still abstract.
If that is the case, changing the inheritance both in CFooer and CSuperFooer from ISomething to virtual will solve the issue (virtual inheritance is designed so that even if the type is mentioned in different levels or branches of the hierarchy tree, all of those that are marked as virtual represent a single unique object. CSuperFooer will have a single ISomething subobject, and the final overrider can be that of CFooer.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why pure virtual function is initialized by 0?
In C++, what does it mean to set a function declaration to zero? I'm guessing it has to do with the function being virtual, and not actually defined in this class. Found in a header file of code that I'm reading:
virtual void SetValue(double val)=0;
What's going on here?
It's a pure virtual function. It makes it so you MUST derive a class (and implement said function) in order to use it.
This is called a pure virtual member function in C++ lingo. It means, as you guessed, that the function is not defined within the class, but rather has to be implemented in deriving classes. You cannot instantiate classes with pure virtual member functions, pure virtual functions basically behave like abstract methods in Java or C#.
It means that it is a pure virtual method - which means subclasses must implement the method on their own. There can still be an implementation for that method, but classes with pure virtual methods cannot be instantiated, making this similar to the abstract keyword seen in various other languages.
if you set a virtual function to set, Its called Pure Virtual Functions. And then your class becomes an abstract class.
You can't create instances of that class or any subclasses unless your pure virtual functions are implemented.
The method SetValue is pure virtual. Its class does not provide the implementation of that method, and can not be instantiated (therefore we term it abstract). Concrete derived classes on the other hand have to provide implementations for such methods. See more here.
It means that, the class is abstract, and can't be create its object. It could be used as a base class to another. Pure virtual class is also used in c++ as an interface known from language like java, but of course it is different.
As everyone has mentioned, this means that the function is a pure virtual function. Think of of this as setting the function pointer to null. Classes with pure virtual functions are handled as abstract classes. This means that derived classes must implement this virtual function.
Occasionally, you may encounter what is called a "pure call" error. This means that a pure virtual function was actually called and it will most likely cause the program to crash. The most common cause of a pure call is that the object that the function was called on was already deleted.
"SetValue" is a pure virtual member function that the base class forces derived classes to provide. Pure virtual member functions will have no implementation.
A pure virtual member function specifies that a member function will exist on every object of a concrete derived class even though the member function is not (normally) defined in the base class.
This is because the syntax for specifying a pure virtual member function forces derived classes to implement the member function if the derived classes intend to be instantiated (that is, if they intend to be concrete).
In your case, all objects of classes derived from the base class will have the member function SetValue(). However, because the base class is an abstract concept, it does not contain enough information to implement SetValue().
Imagine that the "= 0" is like saying "the code for this function is at the NULL pointer."
Pure virtual member functions allow users to write code against an interface for which there are several functionally different variants. This means that semantically different objects can be passed to a function if these objects are all under the umbrella of the same abstract base class.