8

As it is explained in The C++ programming language:

virtual void push(char c) = 0;
virtual void pop() = 0;

The word virtual means 'may be redefined later in a class derived from this one'
The =0 syntax says that some class derived from Stack must define the function.

So why =0 symbol is needed? Does it means that a derived class must define this function, and that's to say when there is no =0, some derived classes are not forced to define this method?

I'm confusing about this, need some help.

hwding
  • 840
  • 10
  • 22
  • 7
    in short: Yes. virtual means they **can** be overridden in a child class. =0 makes this function abstract so It **has to** be overridden. – Hayt Sep 02 '16 at 09:23
  • 1
    You don't have to override virtual = 0 functions. If you don't then the class you defined will be abstract as well. If you plan to actually instantiate a class you will have to override the pure virtual functions eventually. – nwp Sep 02 '16 at 09:33
  • Well having a class without ever instantiating it seems kind of stange though. (Ok in library develeopment maybe it can be valid) – Hayt Sep 02 '16 at 09:37

5 Answers5

5

Your thoughts were right.

So why =0 symbol is needed? Does it means that a child class must define this function, and that's to say when there is no =0, some child classes are not forced to define this method?

Basically you can:

  • Make a method non-virtual

This doesn't allow any class deriving from the class that implements the method (through either public or protected) to change the method's behavior.

  • Make a method virtual

This allows (but doesn't enforce) any class deriving from the class that implements the method (through either public or protected) to change the behavior of the method in the base class. You don't even have to call the original base class method anymore so you can make severe changes if needed.

  • Make a method pure virtual ( virtual = 0 )

This enforces that any class deriving from the class that implements the method (through either public or protected) to implement some kind of behavior/body for this method. If the deriving class does not provide an implementation then this class will instantly become abstract itself. This allows to omit the behavior/body of the method in the base class and because of this it is not allowed to directly instantiate a class that has one or more pure virtual methods (abstract class).

Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
4

So why =0 symbol is needed?

Consider the following:

struct foo
{
    virtual void some() const { cout << "foo" << endl; }
};

struct bar : public foo
{
    virtual void some() const { cout << "bar << endl; }
};

struct baz : public foo
{
}

Suppose you have a pointer foo *p pointing to some object, and you call p->some().

  • If p points to a bar object, it will print "bar".

  • If p points to a baz object, it will print "foo".

In some cases, this might not be what you want. You might want to specify that any derived class needs to override it. The =0 does that.

Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
2

The purpose of an abstract class (those classes have pure virtual method, =0) is to provide an appropriate base class from which other classes can inherit. Abstract classes cannot be used to instantiate objects and serves only as an interface.

Thus, if a subclass of an abstract class needs to be instantiated, it has to implement each of the virtual functions, which means that it supports the interface declared by the abstract class.

That is the base concept for interface.

In short, it a way to be sure a derivative class will implement those methods from the base class.

BiagioF
  • 9,368
  • 2
  • 26
  • 50
2

So why =0 symbol is needed?

Virtual function with sequence = 0 is known as pure virtual function, (the sequence = 0 is known as pure-specifier), it makes the class an abstract class, which can't be instantiated. For the derived classes, if they want to make it possible to be instantiated, they have to implement the pure virtual function.

No objects of an abstract class can be created. Abstract types cannot be used as parameter types, as function return types, or as the type of an explicit conversion. Pointers and references to an abstract class can be declared.

For example,

class Stack {
    virtual void push(char c) = 0;
};
...
Stack s; // Fail, Stack is an abstract class

and if

class Stack {
    virtual void push(char c);
};
...
Stack s; // Fine, if you won't call `push()` on it.
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
1

First consider what is the reason to use virtual methods.

1.Interface(polymorphism).

Interface in C++ is a pure virtual class, which means, that all of its methods are pure virtual (like these two you've mentioned above), it has an virtual destructor and has no constructor (it's obvious, because we can't create its instances). It also shouldn't have any data.

Let's define an interface (pure abstract class in C++):

class Interface
{
public:
    virtual ~Interface(){}
    virtual void somePublicMethod() = 0;
};

And define the class, which is an implementation of interface:

class Implementation : public Interface
{
public:
   ~Implementation() override {}
   void somePublicMethod() override {}
};

If you define another pure virtual method in interface:

virtual void anotherPublicMethod() = 0;

And you don't override it in implementation you will receive compilation error, when you will declare object of Implementation type, because real Implementation object must have definitions (bodies) for all derived methods.

Yo can also define default behavior of some interface's method:

void Interface::somePublicMethod()
{
    //define default behavior here
}

And call it in derived class:

void Implementation::somePublicMethod()
{
    Interface::somePublicMethod();
}

How interface is used in polymorphism you will read in other topics.

2."Ordinary" Inheritance.

In "ordinary" inheritance you should use virtual methods instead of pure virtual ones, because you want to have instances of both Base class and Derived class(es). Virtual methods only indicates, that they could be overridden in derived class(es).

Conclusion

In general, if you want to have an instance of any class, this class must have all methods defined (so the must have bodies and it's obvious that they mustn't be pure virtual).

Community
  • 1
  • 1
Matt Black
  • 31
  • 1
  • 4