[SOLVED][c++]Klasy, zaprzyjaźnianie i dostęp do siebie.

0

Witam !

Mam klasy :


postac //bazowa abstrakcyjna

po niej dziedziczy

player //dziedziczy po postac


skill //bazowa abstrakcyjna

po niej dziedziczy

offence //dziedziczy po skill


Teraz chcę żeby klasa offence miała dostęp do klasy player. Tak wiec załączam odpowiednie nagłówki, oraz zaprzyjaźniam klase offence z player.

Oto fragmenty plików:

postac.h

#pragma once
#include "offence.h"
#include "deffence.h"
{....
   public:

   friend class offence;

...}

player.h

#pragma once
#include "postac.h"

class player :
	public postac

skill.h

#pragma once
#include <iostream>
#include <vector>
#include <string>

offence.h

#pragma once
#include "skill.h"
#include "player.h"


class offence :
	public skill

Jak tak zrobię to co prawda mam dostęp do klasy postac, jak i player z klasy offence, jednak w klasie player która dziedziczy po postac nie mam dostępu do postac, tzn nie rozpoznaje nazw, jak by nie widział deklaracji postac

Widzicie gdzie błędnie wiąże z sobą te klasy ? Domyślam sie że przez #pragma once w player.h nie jest dołączany postac.h jednak jak zrobić żeby był i żeby wszystko działało ?

0

Przyjaźni się nie dziedziczy. Jeżeli zadeklarowałeś przyjaźń z klasą F z klasy podstawowej to potem w klasa pochodna od tej podstawowej nie jest zaprzyjaźniona z klasą F.
Tą deklaracje:
friend class offence;
zamieść w klasie player a nie postać i powinno być ok

0

Dzięki za odpowiedz, jednak nie o to chodziło. Dostęp z klasy offence do player mam, jednak gdy dołączyłem player.h do offence to player nie widzi postac.h i tu jest problem.

0

Spróbuj zamienić w tym pliku.

postac.h

#pragma once
#include "deffence.h"
class offence;            //zmiana na deklaracje zapowiadającą

{....
   public:

   friend class offence;

...}
0

Witam ! Dzięki za odpowiedz jednak nie o to chodzi. Owszem on będzie oczekiwał tej klasy jednak ona nie zostanie nigdy dodana bez #include.

Generalnie to mam 2 pary klas po sobie dziedziczących

klasaA -> KlasaB

klasaC->KlasaD

I chcę mieć dostęp z KlasaB do KlasaD i odwrotnie, zebym mógł tworzyć obiekty w obu klasach.

0

jezeli masz tego typu problemy, to zanim nie zaczniesz dokladnie rozumiec co sie dzieje w naglowkach, forward-declarations, krzyzowych uzyciach/includeach itp, trzymaj swoje pliki .hpp wedlug formatu zblizonego do tego ponizej:

pragma once albo straznik ifndef/define

#include <biblioteka1>
#include <biblioteka2>

class MojaKlasaTutajZdefiniowana;
class MojaKlasaTutajUzywanaPosrednio1;
class MojaKlasaTutajUzywanaPosrednio2;
class MojaKlasaTutajUzywanaPosrednio3;

#include "MojaKlasaTutajUzywanaBEZPosrednio7.hpp"
#include "MojaKlasaTutajUzywanaBEZPosrednio8.hpp"

class MojaKlasaTutajZdefiniowana
{
    friend class MojaKlasaTutajUzywanaPosrednio1;

    MojaKlasaTutajUzywanaPosrednio2 * toTezUzyciePosrednie;
    MojaKlasaTutajUzywanaPosrednio3 & toTezUzyciePosrednieInne;
    
    MojaKlasaTutajUzywanaBEZPosrednio7   aToJestUzycieBezposrednie;
    MojaKlasaTutajUzywanaBEZPosrednio8::cokolwiek   aToJestUzycieBezposrednie;
};

#include "MojaKlasaTutajUzywanaPosrednio1.hpp"
#include "MojaKlasaTutajUzywanaPosrednio2.hpp"
#include "MojaKlasaTutajUzywanaPosrednio3.hpp"

pisane na szybko, moze byc jakis drobny blad, ale taki uklad zaoszczedzi Ci >90% problemow ze zrozumieniem czemu-cos-czegos-tam-nie-widzi-przeciez-mam-include. nie jest to superszablon rozwiazujacy wszystkie problemy, ale powinien Ci wystarczyc

ps. czytaj uwaznie. koncowki Posrednio i BEZPosrednio sa kluczowe

0

Łoooooooo!

Wielkie dzięki, co prawda 30 min przepisywałem deklaracje do tej konwencji ale teraz działa XD. Bardzo dziekuję za pomoc, już nie wiedziałem co zrobić.

Masz racje po części - miałem problem z dołączaniem plików. Nie tyle nie wiem zupełnie jak to działa, bo wiem, że jednego pliku mi nie dołączało z powodu pragmy once, jednak w tej konwencji działa wszystko i jest dołączane wszystko, co należy a wyciane tylko niepotrzebne śmieci.

Masz wielkiego plusa jak z Wrocławia do Gdańska ;p

0
quetzalcoatl napisał(a)

jezeli masz tego typu problemy, to zanim nie zaczniesz dokladnie rozumiec co sie dzieje w naglowkach, forward-declarations, krzyzowych uzyciach/includeach itp, trzymaj swoje pliki .hpp wedlug formatu zblizonego do tego ponizej:

pragma once albo straznik ifndef/define

#include <biblioteka1>
#include <biblioteka2>

class MojaKlasaTutajZdefiniowana;
class MojaKlasaTutajUzywanaPosrednio1;
class MojaKlasaTutajUzywanaPosrednio2;
class MojaKlasaTutajUzywanaPosrednio3;

#include "MojaKlasaTutajUzywanaBEZPosrednio7.hpp"
#include "MojaKlasaTutajUzywanaBEZPosrednio8.hpp"

class MojaKlasaTutajZdefiniowana
{
    friend class MojaKlasaTutajUzywanaPosrednio1;

    MojaKlasaTutajUzywanaPosrednio2 * toTezUzyciePosrednie;
    MojaKlasaTutajUzywanaPosrednio3 & toTezUzyciePosrednieInne;
    
    MojaKlasaTutajUzywanaBEZPosrednio7   aToJestUzycieBezposrednie;
    MojaKlasaTutajUzywanaBEZPosrednio8::cokolwiek   aToJestUzycieBezposrednie;
};

#include "MojaKlasaTutajUzywanaPosrednio1.hpp"
#include "MojaKlasaTutajUzywanaPosrednio2.hpp"
#include "MojaKlasaTutajUzywanaPosrednio3.hpp"

pisane na szybko, moze byc jakis drobny blad, ale taki uklad zaoszczedzi Ci >90% problemow ze zrozumieniem czemu-cos-czegos-tam-nie-widzi-przeciez-mam-include. nie jest to superszablon rozwiazujacy wszystkie problemy, ale powinien Ci wystarczyc

ps. czytaj uwaznie. koncowki Posrednio i BEZPosrednio sa kluczowe

Jak chciałbym cyklicznie używać dwóch klas. Na podstawie powyższego zrobiłem tak jak poniżej. Jeśli na zewnątrz włączane jest tylko #include "FunctionCall.h" to kompilator zwraca, że w FunctionCall.h nie zdefiniowane jest FunctionArgument, jeśli włączam #include "FunctionArgument.h" a po tym #include "FunctionCall.h", to kompilator zwraca, że w FunctionArgument.h nie zdefiniowane jest FunctionCall. Jak używać tych klas cyklicznie?

FunctionCall.h:

 #pragma once
class FunctionArgument;
class FunctionCall
{
	friend class FunctionArgument;
private:
	Token token;
	std::string Name;
	std::vector<FunctionArgument> FunctionArguments;
public:
	inline FunctionCall(Token type, std::string name) : token(type)
	{
		if(identifier == type)
		{
			Name = name;
		}
	}
	inline void AddArgument(FunctionArgument fa)
	{
		FunctionArguments.push_back(fa);
	}
	inline std::vector<FunctionArgument> &GetFunctionArguments()
	{
		return FunctionArguments;
	}
	inline Token GetToken()
	{
		return token;
	}
	inline std::string &GetName()
	{
		return Name;
	}
};
#include "FunctionArgument.h"

FunctionArgument.h:

#pragma once
class FunctionCall;
class FunctionArgument
{
	friend class FunctionCall;
private:
	Token Type;
	std::string String;
	double RealNumerator;
	double RealDenominator;
	bool RealPartIsRatio;
	double ImaginaryNumerator;
	double ImaginaryDenominator;
	bool ImaginaryPartIsRatio;
	char Character;
	std::vector<FunctionArgument> ListElements;
	FunctionCall Call;
	bool isFunctionCall;
public:
	inline Token GetType()
	{
		return Type;
	}
	inline FunctionArgument(FunctionCall call) : Call(call), Type(identifier), isFunctionCall(true) {}
	inline FunctionArgument(char c) : Character(c), Type(character), isFunctionCall(false) {}
	inline FunctionArgument(std::string s, Token type) : String(s), Type(type), isFunctionCall(false) {}
	inline FunctionArgument(double number, Token type) : RealNumerator(number), Type(type), isFunctionCall(false) {}
	inline FunctionArgument(double numerator, double denominator) : RealNumerator(numerator), RealDenominator(denominator),
	Type(ratio), isFunctionCall(false) {};
	inline FunctionArgument(double realNumerator, double realDenominator, bool realPartIsRatio, double imaginaryNumerator, 
	double imaginaryDenominator, bool imaginaryPartIsRatio) : RealNumerator(realNumerator), RealDenominator(realDenominator),
	RealPartIsRatio(realPartIsRatio), ImaginaryNumerator (imaginaryNumerator), ImaginaryDenominator(imaginaryDenominator), 
	ImaginaryPartIsRatio(imaginaryPartIsRatio), Type(complex), isFunctionCall(false) {};
	inline FunctionArgument(Token type) : Type(type), isFunctionCall(false) {};
	inline FunctionArgument(std::vector<FunctionArgument> elements) : ListElements(elements), isFunctionCall(false) {}
	inline FunctionCall GetFunctionCall()
	{
		return Call;
	}
	void Add(FunctionArgument &fa)
	{
		if (Type == intiger && fa.Type == intiger)
		{
			RealNumerator += fa.RealNumerator;
		}
	}
	inline FunctionArgument Subtract(FunctionArgument &fa)
	{
		
	}
	inline double GetRealNumerator()
	{
		return RealNumerator;
	}
	inline bool IsFunctionCall()
	{
		return isFunctionCall;
	}
};
#include "FunctionCall.h"
 

1 użytkowników online, w tym zalogowanych: 0, gości: 1