Использование абстрактных классов с заголовочными файлами в C ++ - PullRequest
2 голосов
/ 20 февраля 2012

Совсем недавно изучил правильное применение наследования классов в Java и подумал применить его к некоторому коду, который я пишу на C ++.

Ниже приведен заголовок для пустого Node.cpp:

#ifndef Node_h
#define Node_h

#include <string>

using namespace std;

///////////////////////////////////////////////////////
//Class Declarations
class Array;
class Hash;
class Node;
    class BodyNode;
        class RealNode;
            class CharNode;
            class ComboNode;
        class EndNode;
    class HashNode;
    class NodeFollower;

///////////////////////////////////////////////////////
//Class Definitions
class Node{
public:
    virtual string toString(int info) = 0;
    };

class BodyNode: public Node{
public:
    };

class RealNode: public BodyNode{
protected:
    Hash *wordHash, *addressHash;
    Array *followers;
    int count;

//Initialization
    RealNode();
    ~RealNode();

//Hashes
    BodyNode getNext(int address);
    NodeFollower getWord(BodyNode *word);
    NodeFollower getAddress(int address);

    string toString(int info);
    };

#endif

Из этого кода я получаю следующую ошибку:

Node.h:43:11: error: invalid abstract return type for member function ‘BodyNode RealNode::getNext(int)’
Node.h:28:7: note:   because the following virtual functions are pure within ‘BodyNode’:
Node.h:25:17: note:     virtual std::string Node::toString(int)

Посмотрел это по всем google, stackoverflow и cplusplus, и в то время как я нашел много ответов, которые окружают эту проблемуЯ не мог найти точный ответ, который мне нужен, чтобы это исправить.Сайт cplusplus.com, с которого я работал, это:

http://www.cplusplus.com/doc/tutorial/polymorphism/

Кроме того, некоторые ответы, которые я нашел в stackoverflow, указали, что

using namespace std;

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

string::string

для каждого объявления, и я пытался

using namespace std::string;

, но оба были безрезультатны.Заранее благодарю за помощь!

Ответы [ 4 ]

3 голосов
/ 20 февраля 2012

Ваша первая проблема заключается в том, что BodyNode наследуется от обычного узла, который имеет toString() чисто виртуальную функцию .Если он чисто виртуальный (= 0), вы ДОЛЖНЫ предоставить определение для него во всех производных классах, а у вас его нет.

Итак, поскольку вы не предоставили определение чисто виртуальной функции в BodyNode, это также абстрактный класс, который не может быть реализован (абстрактный класс имеет 1 или более чисто виртуальных методов, поэтому его нельзя создать).

У вас также есть проблема, которая getNext() возвращает BodyNodeтип, и поскольку BodyNode является абстрактным, это невозможно - вы МОЖЕТЕ вернуть указатель на него вместо значения по-копии, но я думаю, что ваша реальная проблема заключается в том, что он не должен быть абстрактным в первую очередь.

Предоставьте функцию по умолчанию toString() в BodyNode для решения вашей проблемы.

2 голосов
/ 20 февраля 2012

Вы не можете использовать абстрактный класс как тип возвращаемого значения функции.Но вы можете вернуть указатель или ссылку на него, как в следующих объявлениях:

BodyNode* getNext(int address);
BodyNode& getNext(int address);

Вы можете объявить вашу строку как:

#include <string>
...
std::string myString;
0 голосов
/ 20 февраля 2012

BodyNode также является абстрактным классом, потому что - классы, производные от абстрактного класса, должны реализовывать чисто виртуальную функцию, или они тоже являются абстрактными классами.

Вы не можете вернуть объект типа BodyNode. Вы можете только вернуть указатель или ссылку. Обратитесь это-

http://msdn.microsoft.com/en-us/library/c8whxhf1.aspx

0 голосов
/ 20 февраля 2012

Поскольку BodyNode также является абстрактным классом, вы не можете вернуть его из getNext.Вы должны либо вернуть ссылку или указатель.

...