Search code examples
c++pure-virtual

Why can't "PURE" be defined as a const set to 0 to identify pure virtual classes?


Trying to define keyword PURE as a const set to 0, to be used as an identifier for classes that are an abstract data type. Why won't this compile? Per Meyers in "Essential C++, topic 1," I would prefer to use const as opposed to #define, like so:

const int PURE = 0;
virtual void myFunction() = PURE;

Alas, this throws an error (same on Apple LLVM 7.0 and gcc):

Initializer on function does not look like pure-specifier

Example follows, with three techniques labeled A, B, and C;

1. const int PURE = 0 will not compile
2. #define PURE 0 compiles and runs fine
3. Simply setting function = 0 (Stroustrup) works fine.

It's now set up use the const solution, and so will not compile. Simply comment/uncomment lines 4, 5, 11, and 12 appropriately to examine the three different methods:

#include <iostream>
#include <string>

const int PURE = 0;                  // Case B
// #define PURE 0                       // Case C

const float PI = 3.14159;

class Shape {
public:
//    virtual float area() = 0;     // Case A: Compiles
    virtual float area() = PURE;    // Case B: This does not compile
                                    // Case C: Compiles
};
class Circle: public Shape {
public:
    Circle(float radius):radius_(radius) {}
    float area() { return PI * radius_ * radius_; }
private:
    float radius_;
};
class Rectangle : public Shape {
public:
    Rectangle(float base, float height):base_(base),height_(height) {}
    float area() { return base_ * height_; }
private:
    float base_;
    float height_;
};
int main(int argc, const char * argv[]) {
    Circle c(3);
    Rectangle r(3,5);

    std::cout << "Circle Area:    \t" << c.area() << std::endl;
    std::cout << "Rectangle Area: \t" << r.area() << std::endl;

    std::cout << std::endl;
    return 0;
}

Solution

  • The language grammar says:

    pure-specifier:
        = 0
    

    That is, only the tokens = 0 are allowed. You cannot put an identifier there.

    #define PURE 0 works fine because macro replacement happens before translation.