2017-02-06 5 views
1

Попытка определить ключевое слово PURE как const, установленное на 0, для использования в качестве идентификатора для классов, которые являются абстрактным типом данных. Почему это не компилируется? За Мейерс в "Essential C++, в разделе 1," Я предпочел бы использовать const в отличие от #define, например, так:Почему «PURE» не может быть определено как const, установленное в 0, чтобы идентифицировать чистые виртуальные классы?

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; 
} 
+1

Чистый спецификатор '= 0' на самом деле не является выражением присваивания, это просто волшебный синтаксис, поэтому вы не можете заменить ноль переменной; '# define' отлично работает, потому что он работает через необработанную подстановку текста до запуска реального компилятора. –

+0

'# define' работает, потому что обрабатывается препроцессором, поэтому PURE заменяется на 0 и скомпилируется как' virtual float area() = 0' – Anton

+0

Я хотел бы повторить комментарий, который Брайан сделал на его сжатом ответе , Это только хорошая идея в конкурсе по обфускации кода. –

ответ

15

Грамматика языка говорит:

pure-specifier: 
    = 0 

То есть, только маркеры =0 разрешены , Вы не можете поставить идентификатор.

#define PURE 0 работает нормально, потому что замена макросов происходит до перевода.

+0

Итак, если я хочу использовать ключевое слово '' PURE'', как описано выше, у меня нет параметров; Я должен использовать '' # define''? – kmiklas

+7

@kmiklas Да, но вы также просто не должны этого делать.Это путает людей, читающих ваш код. Они будут задаваться вопросом, является ли 'PURE' просто средством' 0' или вызывает ли он какую-то другую магию. – Brian

-1

Просто, чтобы добавить к ответу и комментарию @Brian, ИМХО, для начала это не очень хорошая идея. Это less читается всем, кто действительно понимает этот язык, добавляет абсолютно ничего полезного и не служит никакой полезной цели. В качестве побочного примечания слово «чистый» в CS (особенно функциональные языки) не является вообще, синонимом или эквивалентом «чистого виртуального», используемого в C++ (или таких вещей, как «абстрактный» или «интерфейс» в других языки), поэтому бросайте терминологическую путаницу как потенциальный дополнительный недостаток.

Некоторые люди использовали хотят переходить на «C» из языков, как Pascal с вещами, как это:

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

Это грязно. Это плохая практика на любом языке. В этом случае вы используете C++. Поэтому используйте синтаксис C++. Объявите красоту зверя :)

Извините, слишком многословие для комментария, поэтому пришлось добавить в качестве дополнительного ответа, но оригинальный ответ Брайана правильный и корректный & (и мой голос).