2013-06-06 6 views
0

Я пытаюсь создать простой проект для изучения файлов заголовков и наследования в C++. Я создал файл заголовка:Как создать унаследованный класс из класса из заголовка в C++

Bot.h

#include <vector> 
#include <string> 
#include <cstdlib> 

using namespace std; 

class Bot { 
public: 
    Bot(); 
    ~Bot(); 
    bool initialized; 
    string getRandomMessage(); 
    string getName(); 
protected: 
    vector<string> messages; 
    string name; 
}; 

Тогда я Bot.cpp, где у меня есть

/** 
* 
* @return random message from Bot as string 
*/ 
string Bot::getRandomMessage() { 
    int r = static_cast<double> (std::rand())/RAND_MAX * this->messages.size(); 
    return messages[r]; 
} 

/** 
* 
* @return bot's name as string 
*/ 
string Bot::getName() { 
    return this->name; 
} 

И теперь я не могу понять, как разделить на заголовок и CPP файл и способы обработки включений и других материалов, чтобы все это работало в моем унаследованном классе, которое я выполнил следующим образом:

/** 
* Specialized bot, that hates everything and everybody. 
*/ 
class GrumpyBot : public Bot { 
public: 
    GrumpyBot(); 
}; 

/** 
* Default constructor for GrumpyBot 
*/ 
GrumpyBot::GrumpyBot() { 

    initialized = true; 
    this->name = "GrumpyBot"; 
    messages.push_back("I hate dogs."); 
    messages.push_back("I hate cats."); 
    messages.push_back("I hate goats."); 
    messages.push_back("I hate humans."); 
    messages.push_back("I hate you."); 
    messages.push_back("I hate school."); 
    messages.push_back("I hate love."); 
} 

Когда я использовал все это в одном файле, он работал хорошо, но я не думаю, что это хорошая практика, и я хочу это изучить. Если бы кто-нибудь мог помочь, я был бы рад.

+3

что случилось с вашим кодом сейчас? какую ошибку вы получаете? – pinkpanther

+0

'Bot' нужен« виртуальный »деструктор. И вы не должны «использовать namespace std', * специально * в заголовках. – juanchopanza

ответ

6

Вы уже сделали это для Bot и это то же самое с подкласса:

GrumpyBot.h

#ifndef GRUMPY_BOT_H //this will prevent multiple includes 
#define GRUMPY_BOT_H 
    #include "Bot.h" 
    class GrumpyBot : public Bot { 
    public: 
     GrumpyBot(); 
    }; 
#endif 

GrumpyBot.cpp

#include "GrumpyBot.h" 
GrumpyBot::GrumpyBot() { 

    initialized = true; 
    this->name = "GrumpyBot"; 
    messages.push_back("I hate dogs."); 
    messages.push_back("I hate cats."); 
    messages.push_back("I hate goats."); 
    messages.push_back("I hate humans."); 
    messages.push_back("I hate you."); 
    messages.push_back("I hate school."); 
    messages.push_back("I hate love."); 
} 

Механизм ifndef/define/endif необходим для того, для компилятора не включать заголовок второй раз, когда он анализирует другой, который его включает. Вы также должны изменить свой Bot.h, используя HEADER_NAME_H - это просто конвенция.

+0

Конечно, я пробовал это, но он заставляет меня получать эту ошибку во время компиляции 'Bot.h: 13: 7: error: redefinition of 'class Bot' Bot.h: 13: 7: error: предыдущее определение ' класс Bot'' On ln 12 is include, on ln 13 - это определение класса – Dworza

+0

А это похоже на множественное включение, я отредактирую свой ответ. – Djon

+0

Ну, теперь я получаю различную ошибку. 'GrumpyBot.cpp: 14: неопределенная ссылка на' Bot :: Bot() ''и то же самое для деструктора. Не могли бы вы изменить свой пост еще раз, чтобы показать мне, как это исправить? Я совершенно смущен. – Dworza

3

Разделите свои классы на отдельные заголовки.

Тогда вы будете иметь:

Bot.h

class Bot{ 
    //... 
}; 

GrumpyBot.h

#include "Bot.h" 

class GrumpyBot : public Bot{ 
    //... 
}; 

и сохранить файл .cpp для каждого класса. Затем каждый .cpp включает соответствующий заголовок класса.

На боковой ноте старайтесь избегать использования в заголовках using namespace std;, это довольно неплохая практика, так как это позволит включить эту директиву для всей единицы перевода, в которую входит заголовок, и может быть опасным (это может привести к названию столкновения).

Смежные вопросы