TransWikia.com

C2027: Как правильно настроить композицию классов?

Stack Overflow на русском Asked by ORLADOK on November 5, 2021

Есть 6 файлов:

  • game.h – заголовок, в котором описаны подключения других заголовков.
  • game.cpp – файл, содержащий главную функцию

  • Room.h – заголовок, содержащий описание класса Room
  • Room.cpp – файл, содержащий ТОЛЬКО подключение своего класса: #include "Room.h"

  • House.h – заголовок, содержащий описание класса House
  • House.cpp – файл, содержащий ТОЛЬКО подключение своего класса: #include "House.h"

Проблема заключена в том, что если удалить исполняемые файлы (*.cpp) этих двух классов (Room и House), то программа работает корректно. Иначе же появляется такая ошибка:

Ошибка C2027 использование неопределенного типа “Room”

[D:ProjectsVisual StudioTest-CPPTest-CPPHouse.h: 16]


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


Прилагаю код самих этих файлов (файлы Room.cpp и House.cpp будут в конце списка)

// game.h
#ifndef _GAME_H__
#define _GAME_H__

#include <iostream>
#include <vector>

#include "Room.h"
#include "House.h"

#endif // ! _GAME_H__

// game.cpp
#include "game.h"

int main(void)
{
    House Gomden(0);

    return EXIT_SUCCESS;
}

// Room.h
#ifndef _ROOM_H__
#define _ROOM_H__

#include "game.h"

class Room
{
public:
    Room(unsigned int id)
        : m_id{ id }
    {
        std::cout << "Room #" << id << " was successfully generated!" << std::endl;
    }

    ~Room() { }

private:
    unsigned int m_id;
};

#endif // !_ROOM_H__

// House.h
#ifndef _HOUSE_H__
#define _HOUSE_H__

#include "game.h"

class House
{
public:
    House(unsigned int id)
        : m_id{ id }
    {
        std::cout << "House #" << id << " was successfully generated!" << std::endl;

        unsigned int rooms = rand() % 3 + 1; // 1 .. 3
        for (unsigned int i = 0; i < rooms; i++)
            m_rooms.push_back((class Room)(i)); // <-- здесь есть ошибка, 16 строка
    }

    ~House() { }

private:
    unsigned int m_id;

    std::vector<class Room> m_rooms; // <-- здесь нет ошибки
};

#endif // !_HOUSE_H__

А теперь 2 самых интересных на мой взгляд файла:

// Room.cpp
#include "Room.h"

// House.cpp
#include "House.h"

Классы работают верно в двух случаях:

  1. когда удалены Room.cpp и House.cpp из проекта.

  2. когда все находится в одном файле:

    #include <iostream>
    #include <vector>
    
    class Room
    {
    public:
        Room(unsigned int id)
            : m_id{ id }
        {
            std::cout << "Room #" << id << " was successfully generated!" << std::endl;
        }
    
        ~Room() { }
    
    private:
        unsigned int m_id;
    };
    
    class House
    {
    public:
        House(unsigned int id)
            : m_id{ id }
        {
            std::cout << "House #" << id << " was successfully generated!" << std::endl;
    
            unsigned int rooms = rand() % 3 + 1; // 1 .. 3
            for (unsigned int i = 0; i < rooms; i++)
                m_rooms.push_back((class Room)(i));
        }
    
        ~House() { }
    
    private:
        unsigned int m_id;
    
        std::vector<class Room> m_rooms;
    };
    
    int main(void)
    {
        House Gomden(0);
    
        return EXIT_SUCCESS;
    }
    

Вывод:

House #0 was successfully generated!
Room #0 was successfully generated!
Room #1 was successfully generated!
Room #2 was successfully generated!

One Answer

Проблему решил следующим:

В game.h перед подключением классов добавил прототипы классов:

class House;
class Room;

// затем идет подключение:
#include "Room.h"
#include "House.h"

Для реализации классов (Room.cpp и House.cpp) осталось так:

#include "game.h"

// реализация классов

Answered by ORLADOK on November 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP