ClientClass не называет тип.GCC Linux - PullRequest
3 голосов
/ 16 февраля 2011

При создании кода я столкнулся со странной проблемой. У меня есть 1 файл для всех включений, давайте назовем его include.h и файлы классов, такие как clientclass.h и т. Д.

Проблема в том, что когда я пытаюсь скомпилировать свой код, я получаю ошибку компилятора:

/ мнт / оранжевый новый / ЕД / includes.h | 34 | Ошибка: «ClientClass» не называет тип |

включает в себя: ч:

#ifndef INCLUDES_H_INCLUDED
#define INCLUDES_H_INCLUDED

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>

#include <sys/timeb.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <arpa/inet.h>

#include <time.h>

#include <iostream>
#include <cstring>
#include <string>

#include "config.h"

#include "console.h"
#include "clientclass.h"
#include "tcpparser.h"
#include "netmsg.h"

#include "main.h"

Console Konsola;
ClientClass Clients;

TCPThread ParserTCP;

#endif // INCLUDES_H_INCLUDED

clientclass.h:

#ifndef CLIENTCLASS_H_INCLUDED
#define CLIENTCLASS_H_INCLUDED

#include "includes.h"

struct ClientStruct {

    int Sock;
    int Ident;
    int Room;

    std::string Name;
    std::string IP;

};

class ClientClass {
    public:
        ClientClass(); // create

        int Add();
        void Delete(int index);
        int Count();

        ClientStruct Client[MAX_CLIENTS];

    protected:
        void Reset(int index);

    private:
        int _count;

};

#endif // CLIENTCLASS_H_INCLUDED

Можете ли вы помочь мне с моей проблемой? я вне идей: (* ​​1015 *

Ответы [ 5 ]

5 голосов
/ 16 февраля 2011

У вас есть круговая зависимость: includes.h -> clientclass.h -> includes.h. Как это решить, зависит от того, какой заголовок будет включен первым, но это всегда будет сбивать с толку. Скорее всего это вызывает линию

#include <clientclass.h>

для успешного выполнения, но не для включения содержимого, так как защита для включения CLIENTCLASS_H_INCLUDED уже была определена, хотя содержимое еще не существует.

Чтобы решить эту проблему, вы можете просто удалить включение includes.h из clientclass.h, если оно не используется ни для чего. Если вы используете типы из includes.h, вы можете использовать предварительные объявления, которые объявляют, что класс существует без его определения, например,

class ClientClass;

Таким образом, вы можете использовать указатели и ссылки на ClientClass без необходимости включать clientclass.h. Чего вы не можете сделать, так это объявить значения объявленных вперед типов, так как компилятор должен знать все о типе (по крайней мере, насколько он велик), прежде чем он сможет зарезервировать память для значения этого тип. Если вам это нужно, возможно, вам придется разбить заголовок на более мелкие части и включить только малую часть, от которой вы зависите.

Так, например, вы можете сделать следующее:

class MyClass;

MyClass * globalPointer;

void doSomething(const MyClass & foobar);

без определения MyClass в области видимости. Два выражения здесь используют MyClass только через указатель или ссылку. Но следующее не сработает:

class MyClass;

void doSomethingElse() {
    MyClass theobject;
    doSomething(theobject);
}

Для этого требуется зарезервировать место в стеке для объекта типа MyClass. Без определения MyClass в области видимости компилятор не сможет узнать, сколько памяти выделить.

В вашем случае вы определяете глобальные значения типа ClientClass, и для этого требуется полное определение ClientClass, а не просто предварительное объявление. У вас есть несколько вариантов:

  • Далее разбейте включаемые файлы, чтобы вы могли включить только малую часть, которая вам нужна
  • Удерживайте ваше глобальное значение указателем и выделите его где-нибудь позже в коде после того, как вы включили полное определение ClientClass

Другой вариант - пересмотреть, являются ли глобальные переменные здесь правильным решением.

4 голосов
/ 16 февраля 2011

Я немного смущен, почему у вас есть clientclass.h, который включает в себя include.h, который включает в себя clientclass.h

Я думаю, что проблема может быть где-то там.Вы не должны этого делать.

0 голосов
/ 16 февраля 2011

после попытки использовать предварительное объявление я получаю сообщение об ошибке:

/ мнт / оранжевый новый / ЕД / includes.h | 37 | Ошибка: совокупность клиентов ClientClass неполный тип и не может быть определен |

редактирование: Разбиение включает в себя .h на 2 файла classes.h и включает в себя .h решил проблему. Я очень благодарен всем за помощь. Я никогда не ожидал так много ответов за такое короткое время :) ожидайте, что я буду здесь чаще. Спасибо.

0 голосов
/ 16 февраля 2011

Поскольку ваши заголовки размещены, было бы невозможно включить "clientclass.h" где-либо еще, кроме как из "includes.h". Это связано с тем, что в этом случае глобальные экземпляры будут объявлены до определения классов в "clientclass.h"

Если вы включите «clientclass.h», то первое, что он сделает, - это включит «include.h», включая глобальные переменные, объявленные с ним.

Попробуйте включить только то, что нужно заголовку "clientclass.h" : <string> (и заголовок, откуда берется MAX_CLIENTS).

0 голосов
/ 16 февраля 2011

Может быть, это из-за перекрестного включения ... Вы пробовали предварительное объявление типа, добавив

class ClientClass;

внутри includes.h до ClientClass Clients

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