为什么不能" PURE"被定义为一个const设置为0来识别纯虚拟类?

时间:2017-02-06 21:27:04

标签: c++ pure-virtual

尝试将关键字PURE定义为0的const集,以用作抽象数据类型的类的标识符。为什么不能编译? Per Meyers in" Essential C ++,topic 1,"我宁愿使用const而不是#define,如下所示:

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

唉,这会引发错误(在Apple LLVM 7.0和gcc上也是如此):

Initializer on function does not look like pure-specifier

以下示例,标记为A,B和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.

现在设置使用const解决方案,因此无法编译。简单地评论/取消注释第4,5,11和12行,以检查三种不同的方法:

#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;
}

2 个答案:

答案 0 :(得分:15)

语言语法说:

pure-specifier:
    = 0

也就是说,只允许使用令牌= 0。你不能在那里放一个标识符

#define PURE 0正常工作,因为宏替换发生在翻译之前。

答案 1 :(得分:-1)

只是为了添加@Brian的答案和评论,恕我直言,这不是一个好主意。对于任何真正了解语言的人来说, 可读,绝对没有任何价值,也没有用处。作为旁注,CS中的“纯”一词(特别是函数式语言)并非同义或等同于C ++中使用的“纯虚拟”(或“抽象”或“界面”在其他语言中),所以将术语混淆作为潜在的额外缺点。

有些人过去常想从像Pascal这样的语言过渡到“C”:

#define BEGIN {
#define END   }
// etc...

太乱了。这在任何语言中都是不好的做法。 在这种情况下,您使用的是C ++。所以使用C ++语法。拥抱野兽的美丽:)

对不起,对于评论过于罗嗦,所以不得不添加作为额外答案,但@ Brian的原始答案是正确的&amp;简洁(并得到我的投票)。