Abstract class with pure virtual method - why is it possible to do "Abstract * abs3;"?
Consider the following :
class Abstract
{
public:
virtual void f开发者_JAVA技巧unc() = 0;
};
int main() {
Abstract abs1; // doesn't compile
Abstract * abs2 = new Abstract(); // doesn't compile
Abstract * abs3; // compiles
return 0;
}
Please notice that I didn't implement func()
, so why is it possible to do Abstract * abs3;
where we have a pure virtual method and an abstract class ?
I know that I'd get a run-time error if I'd try to do abs3->func(); , but still , it's not clear to me why C++ allows that code to compile ...?
thanks ,Ron
abs3
is a pointer to the class. It can be initialized to any concrete subclass of Abstract, or to NULL, safely. The compiler has to allow it because while you can't create abstract classes, you have to be able to create pointers to them. See below for an example
class Concrete: public Abstract
{
public:
virtual void func() { // do something };
};
int main ()
{
Abstract* abs3 = NULL;
abs3 = new Concrete;
}
You cannot instantiate an abstract class, but it is perfectly OK to have a pointer to it. This is in fact very often used in OO design.
Short Answer
The compiler does not issue any error because it is perfectly fine to create an pointer to an Abstract Class.
Long Answer
Unless, In order to instantiate a class and create objects of an type the compiler needs to knows the composition of that type.
You can create an pointer to an Abstract class, because all pointers on an system have the same size regardless of the type they point to.
Note that creating a pointer does not call the constructor.
You cannot create an object of the Abstract class because the class has some method which is not completely defined and hence the compiler does not know the composition of the class. Thus, forbidding it's instantiation.
EDIT:
Even if you provide an definition to a pure virtual function(and it perfectly valid to do that) You still cannot instantiate a Abstract class because the moment you declare a function as pure virtual, the compiler treats the class as abstract(Incomplete) and it cannot be instantiated anymore.
Actually, the point in having the possibility to create a pointer to an abstract class is to point it to (concrete) classes that derive from the abstract class:
class Abstract
{
public:
virtual void func() = 0;
};
class Derived1 : public Abstract
{
public:
virtual void func() { /* do something */ }
}
class Derived2 : public Abstract
{
public:
virtual void func() { /* do something else */ }
}
and then, for example:
Abstract * ap;
if (/*something*/)
ap = new Derived1();
else
ap = new Derived2();
ap->func();
delete ap;
Inheritance is the key idea you're missing. If Vehicle
is abstract, and a Car
is a vehicle, then Vehicle*
is a perfectly valid type for a pointer to an instantiated Car
. The abstract base class is a valid type as an argument to a method (reference), and whether a Car
or a Bike
is passed, the correct virtual implementation of func
will be called. It's a key feature of the language.
You simply can't have an instance of a class where one or more methods have not been implemented.
What you are trying to do here is having instances of a class which has a pure abstract method named func()
: this is not possible.
Abstract * abs3
compiles being an uninitialized pointer, there you are not allocating any instance of Abstract
.
Abstract abs1;
Abstract * abs2 = new Abstract();
will never compile.
You should specify Abstract
(through inheritance) providing an implementation for func()
and at that point you would be able of having instances of such derived class.
精彩评论