Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
1.00/5 (4 votes)
See more:
#include
C#
<iostream>

using namespace std;

class Base
{
 public:
    virtual void diplay() = 0;
};

//Main function
int main()
{
Base B;
}
Posted
Comments
[no name] 14-Jul-15 11:15am    
https://msdn.microsoft.com/en-us/library/k535acbf(VS.71).aspx
CPallini 15-Jul-15 9:09am    
In my opinion, that's similar to asking: "why a const value cannot change?"

The whole idea of an abstract class is that it is "an abstraction" - it defines what the concrete classes must do.

If you could instantiate it, it wouldn't be an abstract class, it would be a "normal" class that didn't work because some of the vital bits were missing!

It's like a car: your car is a Ford, my car is a Mercedes. "Car" is an abstract class that doesn't exist on it's own, but it can contain functions which apply to all Car objects: "Accelerate", "Brake", "Steer", and "Start" for example. But you need to have a motor manufacturer in order to drive: "Ford" and "Mercedes" are derived from "Car" but they implement the "Start" method (by turning a key in the one case, by pressing a button in the other)

See here for another explanation: http://www.studytonight.com/cpp/abstract-class-and-pure-virtual.php[^]
 
Share this answer
 
Because this is the purpose of the notion, to prevent instantiation of abstract classes.

In this case, the class can be called abstract, because it contains at least one pure virtual function (the one with "= 0" following the declaration, display in the code sample), which also can be called "abstract". Imagine what would have happened if you could instantiate such class:
C++
Base b;
b.display(); // crash!

Note that it is impossible for the compiler to deny compilation of b.display(), because this line could be valid if the runtime type of b wasn't Base, but was a class derived from Base, with properly overridden display(). And this is the whole idea of the purpose of abstract classes: to serve as a base class for derived classes and provide a common interface for them. In such cases, the compile-time type of instantiated object could be the base class, but all actual runtime types should be all non-abstract. This is enforced by having the compiler preventing instantiation of abstract types (class or struct).

[EDIT]

Thanks to the important comments by Stefan Lang (please see below), I improved the answer. I removed the mention that the pure virtual function has no implementation, because it can have one: http://en.cppreference.com/book/intro/abstract_classes[^].

Adding the implementation does not make a type non-abstract; the implementation can be used for whatever purpose in the derived classes. When the using code calls this function, such outside call will always be dispatched to one of the implementations of this function in one of derived classes, because overriding of the pure virtual function is required to make a non-abstract type; and only a non-abstract type can be instantiated.

Also, in my comment to the question, I explained in what cases the compiler cannot deny the compilation of b.display(). Of course, in principle, the compiler could analyze and find out that this line makes no sense, based on the declaration of b. But let's consider the cases when this is not so.

For example,
C++
class Base {/* ... */} // abstract, same as in the inquirer's code sample
class Derived : public Base {/* ... */} // display implemented, non-abstract

Let's say we have function
C++
void SomeExample(Base* b) { b->display(); }
or
C++
void SomeExample(Base& b) { b.display(); }

Should it compile? Yes, always. This is because the function does not "know" the runtime type of b. It can be called with any of the derived types, and Base serves as a common interface for them.

Note that, in the last code sample, the line which should compile is exactly the same as in the very first "impossible" code sample: b.display(); but in this context it should compile and will work, exactly by the reason I started with: the runtime type of b cannot be Base, the compiler will prevent instantiation of an abstract class.

—SA Codeproject Bot
 
Share this answer
 
v10
Comments
Stefan_Lang 15-Jul-15 3:07am    
I object to your second sentence:
"... at least one virtual function, which is a virtual function without implementation."
Maybe it's just a case of bad formulation, but I'm sure you know that even a pure virtual function can have an implementation ;-)

Also, I find the hypothetical part (what if) somewhat confusing: it isn't entirely clear what is part of the assumption and what a fact. E. g. the compiler could never accept b.display, because b is of type Base, and it can't possibly be another type in truth - that would require b to be a reference or pointer. Are you making another assumption here?
Sergey Alexandrovich Kryukov 15-Jul-15 6:54am    
No, I don't know it. It could be a matter of definitions (not even formulation), so could you please explain to me, 1) what would you mean by "virtual function without implementation", 2) show any example of such function, 3) explain how could it possibly work (if possible, how it is implemented internally), 4) perhaps explain its purpose.

I would be much grateful.

As to the second part, no, I'm not doing any assumption, but I just didn't know how to explain it better but in brief. First of all, in real compiler and this exact code sample, d.display() will always be denied, but only because the compiler can figure out that the type is abstract.

We can build an example when it is theoretically impossible. Let's say, you have
class Base {/* ... */} // abstract

class Derived : abstract Base {/* ... */} // display implemented, non-abstract

Let's say we have function
void SomeExample(Base* someObject) { someObject->display(); }
or
void SomeExample(Base& someObject) { someObject.display(); }

Should it compile? Yes, always. This is because the function does not "know" the runtime type of someObject. It can be called with any of the derived types, and Base serves as a common interface for them. Will you agree now?

Thank you.
—SA
Stefan_Lang 15-Jul-15 8:12am    
As for the first, a pure virtual function can have an implementation. You can find some more info and examples here: http://stackoverflow.com/questions/2089083/pure-virtual-function-with-implementation

Also, here is a somewhat more official article that covers this: http://en.cppreference.com/book/intro/abstract_classes

In short, while you can provide implementations for the abstract functions of a class, this still does not allow you to create an instance of that class. A possible use case for doing this would be to provide some default behaviour that a derived class can choose to invoke by calling the base method explicitely.

As to the second part, you might consider it nitpicking, but in your example code you declared b as Base, not Base& or Base*. I did say that for b to 'be' (in fact, refer to) a different type, it would need to be a reference or pointer.
Sergey Alexandrovich Kryukov 15-Jul-15 8:25am    
Thank you very much. Yes, I got it. Pure virtual can really be implemented and remain pure virtual. It can be used by derived classes.

As for the second part, I already admitted that I just did not find how to explain this thing better. I hope you will agree with my explanations in the comment. I'll add a note to the question, to avoid confusions.

Your notes have been really valuable, thank you.

—SA
Sergey Alexandrovich Kryukov 15-Jul-15 8:47am    
Please see new version of my answer. I credited your comments.
Thank you again.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900