Ошибка компиляции при использовании наследования C ++ - PullRequest
0 голосов
/ 13 января 2010

Я новичок в этом сайте, и я пытаюсь простой пример наследования в C ++. Я проверял свой код много раз и действительно не вижу в этом ничего плохого, однако компиляторы выдают мне ошибки:

мой код:

#ifndef READWORDS_H
#define READWORDS_H
using namespace std;
#include "ReadWords.h"

/**
 * ReadPunctWords inherits ReadWords, so MUST define the function filter.
 * It chooses to override the default constructor.
 */

class ReadPunctWords: public ReadWords {
    public:
    bool filter(string word);
};

#endif

И сообщения, которые я получаю от компилятора:

ReadPunctWords.h:11: error: expected class-name before '{' token
ReadPunctWords.h:13: error: `string' has not been declared
ReadPunctWords.h:13: error: ISO C++ forbids declaration of `word' with no type

Tool completed with exit code 1

Я действительно не уверен, где я ошибаюсь, поскольку для меня это выглядит нормально? Спасибо за любые ошибки, которые вы можете заметить.

Ответы [ 5 ]

12 голосов
/ 13 января 2010

Вы должны включить строку:

#include <string>

Тем не менее, не используйте using namespace! Особенно в области видимости файла, а определенно не в заголовочном файле. Теперь любой юнит, который включает этот файл, вынужден поддаться всему в пространстве имен std.

Возьми это и уточни свои имена:

bool filter(std::string word);

Это также более читабельно. Кроме того, вы должны принять вашу строку как const&:

bool filter(const std::string& word);

Чтобы избежать ненужного копирования строки. Наконец, ваши охранники заголовка кажутся выключенными. Должны ли они быть изменены? На данный момент они похожи на те, которые будут использоваться в вашем другом заголовке, что может эффективно помешать его включению.

Если вы определите READWORDS_H, а затем включите ReadWords.h, и если оно также имеет:

#ifndef READWORDS_H
#define READWORDS_H

Тогда ничего в этом файле не будет обработано. Если это так, ReadWords как класс не будет определен, и вы не можете наследовать от него. Ваша охрана, вероятно, должна быть:

READPUNCTWORDS_H
2 голосов
/ 13 января 2010

Вам необходимо включить <string> и указать пространство имен:

<code>#include <string>
<strike>using namespace std;</strike>

Кроме того, ваш включенный охранник, вероятно, должен иметь имя READPUNCHTWORDS_H, а не READWORDS_H.

Редактировать: Если подумать, GMan прав, что не поместил using namespace в заголовочный файл - вместо этого укажите строку std::string.

1 голос
/ 13 января 2010

Эта конкретная форма ошибки часто вызвана тем, что тип не определен (по крайней мере, когда код выглядит синтаксически правильным), в этом случае, вероятно, класс ReadWords, но, возможно, также std :: string.

Вам нужно включить, чтобы получить std :: string, как написали другие авторы, но также и вашу охрану

#ifndef READWORDS_H
#define READWORDS_H

почти наверняка конфликтует с охранником в ReadWords.h. Вы должны убедиться, что ваши охранники различны в разных заголовочных файлах, иначе вы получите такие конфликты. Вы должны сменить охрану на что-то вроде

#ifndef READPUNCTWORDS_H
#define READPUNCTWORDS_H

// ...

#endif

На самом деле, лучше иметь еще больше многословных охранников, чтобы они не конфликтовали. Мы используем охранники формы

#ifndef MODULE_OR_PATH_FILE_H_INCLUDED
#define MODULE_OR_PATH_FILE_H_INCLUDED

// ...

#endif

Это гарантирует, что различные модули или библиотеки с одинаково названными заголовками не будут конфликтовать, в конце включена вещь INCLUDED - моя собственная слабость, которая делает охрану немного более читабельной.

Также неправильно размещать объявление «using» в заголовочном файле, поскольку оно помещает (потенциально нежелательные или конфликтующие) символы в глобальное пространство имен везде, где вы включаете заголовок. Лично я предпочитаю сохранять пространство имен для ясности или псевдоним его в файлах cpp, если оно длинное, например

namespace fs = boost::filesystem;
0 голосов
/ 13 января 2010

Я также подозреваю, что охранники включают. Если в обоих заголовочных файлах они названы одинаково, то при вставке файла ReadWords.h в файл ReadPunctWords.h результат должен быть примерно таким:

#ifndef READWORDS_H // Is READWORDS_H defined? No, proceeding
#define READWORDS_H // Now it is defined

// Contents of ReadWords.h is pasted in here
#ifndef READWORDS_H // Is READWORDS_H defined? Yes, ignoring the contents of ReadWords.h (skipping til #endif)
#define READWORDS_H

class ReadWords { ... }; // This is never seen by the compiler as the preprocessor removed it

#endif

class ReadPunctWords: public ReadWords { // Error: ReadWords isn't declared...
public:
    bool filter(string word);
};

#endif
0 голосов
/ 13 января 2010

также выглядит как-то не так с классом def ReadWords (сообщение для строки 11) - нам нужно посмотреть файл .h

aha - используемый вами ответный пароль предотвращает чтение readwords.h, включая чтение

вам нужно

 #ifndef _READPUNCTWORDS_H
 #define _READPUNCTWORDS_H
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...