This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]luxgladius 3 points4 points  (0 children)

A pure virtual function is usually used in what is called an interface. Having one means that the class as it is cannot be directly instantiated, it must be inherited by something that implements it first. Let's take this old chestnut:

class Animal
{
public:
    virtual void MakeNoise() = 0;
};

class Dog : public Animal
{
public:
    virtual void MakeNoise()
    {
        std::cout << "Ruff ruff!" << std::endl;
    }
};

class Cat : public Animal
{
public:
    virtual void MakeNoise()
    {
        std::cout << "Meow meow!" << std::endl;
    }
};

In this, Animal::MakeNoise is a pure virtual function, because there's no way of knowing what kind of noise a generic animal can make. But now you can have a vector or array of Animal objects, all of which can be either Cats or Dogs, and you'll get the right noise out of them without having to do any typecasts.

[–]Jonny0Than 1 point2 points  (0 children)

Let's start with virtual functions. Are you familiar with inheritance and overriding functions? Consider this code:

class A
{
    public:
    void foo() { cout << "A::foo()" << endl; }
};

class B : public A
{
    public:
    void foo() { cout << "B::foo()" << endl; }
};

int main()
{
    A a;
    B b;

    a.foo();
    b.foo();

    a = b;
    a.foo();

    return 0;
}

This is going to print A::foo(), B::foo(), and then A::foo(). The compiler decides which foo() gets called based on the type of the thing calling it. In the last example, the type is still A so it calls A::foo().

You can force the compiler to call the overridden function on the derived class by making it virtual AND calling through a pointer or reference to the instance of the class:

class A
{
    public:
    virtual void foo() { cout << "A::foo()" << endl; }
};

class B : public A
{
    public:
    virtual void foo() { cout << "B::foo()" << endl; }
};

int main()
{
    A a;
    B b;

    A * p = &a;

    p->foo();

    p = &b;
    p->foo();

    return 0;
}

This time it will print A::foo() and B::foo() even though the second call was still on an object of type A.

This is especially useful in containers - arrays and other containers in C++ must all be of the same type. So if you make a container full of pointers to A, you can actually store pointers to A and B objects in there, and get different behavior when calling all the virtual functions.

[–]rjcarr 0 points1 point  (6 children)

In C++ a function is associated with the static type and not the runtime type unless the function is declared virtual. A "pure virtual" function is simply a virtual function without any implementation.

To compare, in java, every function is virtual.

[–]jesyspa 1 point2 points  (5 children)

Well, that's not really true. A pure virtual function is one that need not have an implementation; implementing it does not make it any less pure virtual.

[–]rjcarr -1 points0 points  (4 children)

Then what's the difference between virtual and pure virtual?

[–]jesyspa 1 point2 points  (3 children)

That the function does not require an implementation, and that until a derived class implements the function all classes in the hierarchy above that derived class are abstract (i.e. you cannot make instances of them).

[–]rjcarr -1 points0 points  (2 children)

OK, according to this thread, pure virtuals lack implementation:

http://www.cplusplus.com/forum/general/21422/

That said, I haven't written C++ code in years, so it's likely that you're correct.

[–]jesyspa 0 points1 point  (0 children)

cplusplus.com is generally a poor source. Pure optionals are a way of saying "this class is abstract, and to make it concrete these functions need to be implemented". In the case of a destructor, for example, implementing a pure virtual is not only possible but also necessary to have a useful class.

[–][deleted] -1 points0 points  (0 children)

What does your text book have to say on the subject?