• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dołączanie plików nagłówkowych c++

Object Storage Arubacloud
0 głosów
1,445 wizyt
pytanie zadane 15 września 2016 w C i C++ przez timrh Mądrala (6,030 p.)

Witam, stworzyłem klasy struktury opisujące animacje, przyciski i pola edycji w SFML. Wcześniej miałem je wszystkie w pliku głównym .cpp, jednak miałem problem ponieważ jedne potrzebowały drugich a drugie pierwszych a tak nie może być w takim zapisie. Jeżeli dałem wyżej zapis:

class Button;

Po to aby tylko pokazać że taka klasa wystąpi niżej, wywalało mi to błąd, że używam niezdefiniowanej klasy Button. No więc postanowiłem wszystkie te klasy poumieszczać w plikach nagłówkowych i potem je połączyć ze sobą i z programem. Wyszło mi w sumie 8 plików nagłówkowych i mam problem bo gdy np. W jednej klasie napiszę metodę:

struct IObject
{
	void SendToMenu(Button sender)  //Błąd - niezdefiniowana klasa Button
	{
		switch (menu_type)
		{
		case menu::game:
			Game.AllButtons.push_back(&sender);
			break;
		}
	}

	virtual ~IObject() {};
};

I dołączę inny plik nagłówkowy przechowujący klasę button aby nie wywaliło błędu o niezdefiniowanej klasie to i tak mi wywala ten błąd. Jeżeli wyżej dopiszę : class Button; To i tak wywali, i mam teraz 63 błędy dotyczące niezdefiniowanych klas. Ktoś mi powie jak mogę połączyć tak aby synchronicznie się uzupełniały? Z góry dziękuję!

 

komentarz 15 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
Czy przy dołączaniu plików nagłówkowych zachowałeś podobną kolejność, którą miałeś w jednym kodzie? Tzn. jeden plik nagłówkowy widzi kolejny plik nagłówkowy, który zawiera potrzebne/poprzednie dane, czy może wszystko przyincludowałeś w głównym cpp z main'em?
1
komentarz 15 września 2016 przez timrh Mądrala (6,030 p.)
No tak, struktura IObject korzysta z klasy Button, Button zaś z IObject (dziedziczy z niej) więc w obu zrobiłem include'y do siebie nazwajem.
komentarz 15 września 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 15 września 2016 przez plkpiotr

Ok, w takim razie bez wglądu na kod nie mam pomysłu jak to ugryźć...
Napisałem o tym na co ja się nadziałem podczas podziału kodu na pliki, może ktoś mądrzejszy ode mnie będzie miał pomysł jak problem rozwiązać...

Ja jednak w swoich projektach dołączam tylko jeden plik nagłówkowy do kolejnego wtedy ten poprzedni ma już jakby dołączone pozostałe...

komentarz 15 września 2016 przez draghan VIP (106,230 p.)
Poczytaj temat, który wyświetla się na dole strony z Twoim pytaniem - przewiń teraz na dół i sprawdź.
komentarz 15 września 2016 przez timrh Mądrala (6,030 p.)
Poczytaj mój temat, w którym wyraźnie jest napisane że definicja klasy nie działa.
komentarz 15 września 2016 przez draghan VIP (106,230 p.)
...i w którym nie podajesz kodu źródłowego. Poczytałem.
komentarz 15 września 2016 przez timrh Mądrala (6,030 p.)
#pragma once

#include "SFML\Graphics.hpp"
#include "ButtonEvent.h"
#include "IObject.h"
#include "IColorable.h"
#include "IVisualisable.h"
#include <vector>

using namespace std;

vector<Button> buttons;
struct IObject;
struct IVisualisable;
struct IColorable;

class Button sealed : public IObject, public IVisualisable, public IColorable
{
private:
	string button_value;
	Color button_color;
	Color text_color;
public:
	vector<ButtonEvent> button_events;

	string GetButtonValue()
	{
		return button_value;
	}

	Color GetTextColor()
	{
		return text_color;
	}

	//play effects after pressig button
	void PlayEvent()
	{

		for (int i = 0; i < button_events.size(); i++)
		{
			//cout << "ok - sended from button with id: " << this->ID << "\n";
			if (button_events[i].CheckConditions())
			{
				button_events[i].StartEffect();
			}
		}
	}

	void AddEvent(ButtonEvent button_event)
	{
		button_events.push_back(button_event);
	}

	Button(Vector2f position, Vector2f size, string button_value, Color text_color, Color normal_color, Color pressed_color, menu menu_type)
	{
		this->position = position;
		this->size = size;
		this->button_value = button_value;
		this->button_color = normal_color;
		this->text_color = text_color;
		this->active_background_color = pressed_color;
		this->normal_background_color = normal_color;
		this->ID = buttons.size() > 0 ? buttons.size() : 0;
		this->menu_type = menu_type;

		SendToMenu(*this);

		buttons.push_back(*this);
	}

	void SetColor(bool clicked)
	{
		button_color = clicked ? active_background_color : normal_background_color;
	}

	~Button() {};
};

 

#pragma once
#include "Button.h"
#include "Menu.h"

class Button;

struct IObject
{
	menu menu_type = menu::game;
	bool enabled = true; //set active in start of game

	void SetActive(bool enable)
	{
		//cout << "Disabling button with ID: " << this->ID << endl;
		enabled = enable;
	}

	void SendToMenu(Button sender)
	{
		switch (menu_type)
		{
		case menu::game:
			Game.AllButtons.push_back(&sender); //zawarte w nagłówku Menu.h
			break;
		}
	}

	virtual ~IObject() {};
};

 

komentarz 15 września 2016 przez draghan VIP (106,230 p.)
Powiedz jeszcze, który fragment kodu jest w jakim pliku.
komentarz 15 września 2016 przez timrh Mądrala (6,030 p.)
Struktura IObject w IObject.h, klasa Button w Button.h
komentarz 15 września 2016 przez draghan VIP (106,230 p.)
Rozdziel definicje od deklaracji. Deklaracje umieść w nagłówkach, zaś definicje w plikach kompilowanych. Z nagłówków pousuwaj zbędne includy - tzn. takie, bez których kompilator będzie miał nadal wystarczającą ilość informacji o typach, by móc budować Twój program dalej.

Wszystkie wymagane nagłówki muszą się znaleźć natomiast w plikach kompilowanych.

1 odpowiedź

0 głosów
odpowiedź 16 września 2016 przez criss Mędrzec (172,590 p.)

Definicje klas umieszczaj w plikach *.h / *.hpp a definicji metod w *.cpp. Następnie w plikach *.h / *.hpp nad definicją klasy dopisuj deklaracje istnienia potrzebnych klas, a w plikach *.cpp #include.

Przykładowo:

C1.h :

#pragma once

class C2;
class C3;

class C1
{
void m1(C2, C3);
};

C1.cpp:

#include "C1.h"

#include "C2.h"
#include "C3.h"

void C1::m1(C2 a, C3 b)
{
...
}

I nie powinno być problemu. Możesz też sobie poczytać : http://www.cplusplus.com/forum/articles/10627/

Podobne pytania

0 głosów
1 odpowiedź 422 wizyt
0 głosów
2 odpowiedzi 519 wizyt
0 głosów
1 odpowiedź 497 wizyt
pytanie zadane 17 grudnia 2021 w C i C++ przez Czarus Obywatel (1,310 p.)

92,573 zapytań

141,423 odpowiedzi

319,648 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...