Skocz do zawartości

klasy


DevPort

Polecane posty

Dobra miałem pewien problem ze strony kompilatora C++

 

struktura klas:

class A
{
public:
  A(){ b = new B; c = new C;}
  B* b;
  C* c;
};

Teraz magiczne zdanie:

Chciałem dostać się z klasy B do klasy C.

 

Główkowałem cały dzień jak to zrobić, kombinowałem z interfejsami (w delphi/fpc to nie problem) ale poległem.

Przyszedł mi jednak pewien pomysł na rozwiązanie problemu.

Przekazanie instancji klasy A do pozostałych klas czyli B i C przez konstruktor.

 

Czyli tu mamy błędny kod:

B::B(A* base)
{
}

C::C(A* base)
{
}

Ponieważ musimy do plików nagłówkowych klas B i C dołączyć plik nagłówkowy klasy A który zawiera w sobie dołączone pliki nagłówkowe klas B i C.

 

Więc jak?

W ukochanym Object Pascalu mamy wskaźnik niejawny : Pointer; 4 bajtowy.

W C++ odpowiednikiem jest "void* zmienna;"

 

Ta, wielu więc napisze: to proste więc zamieńmy w konstruktorach A* na void* i po sprawie...

Ne ne ne

 

Kompilatorek wywali błąd konwersji :)

I tu szczena mi opadła :(

 

Ale coś musi być, aby to działało i jest:

static_cast

 

więc tak piszę w/g plików:

"a.h"

#include "B.h"
#include "C.h"

class A
{
public:
 A();
 B* b;
 C* c;
}

 

"a.cpp"

#include "A.h"
A::A()
{
 b = new B(this);
 c = new C(this);
}

 

Teraz pliki pozostałych klas:

"b.h"


class B
{
public:
 B( void* base);

}

 

"b.cpp"

#include "B.h"
#include "A.h"

A* mA;
B::B(void* base)
{
 mA = static_cast<A*>(base);
}

 

 

"c.h"


class C
{
public:
 C( void* base);
 void test();
}

 

"c.cpp"

#include "C.h"
#include "A.h"
#include <iostream>

A* mA;
C::C(void* base)
{
 mA = static_cast<A*>(base);

}

void C::test()
{
std::cout << "Witaj świecie \n";
}

 

Teraz w metodach klasy B możemy używać zapisu:

 mA->c->test();

 

 

Komuś może się przydać taka konstrukcja kodu.

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

Ojojoj... W C++ void * należy używac w ostateczności (czyli uzycie takiego to z prawdopodobieństwem 1 użycie błędne).

Dodatkowo zmienne globalne... brrr....

 

Podpowiedć, np plik c.h może wyglądac tak:

 

class A;
class C
{
public:
 C( A* base);
 void test();
}

Link do komentarza
Udostępnij na innych stronach

Testowałeś to ?

Możesz podać działający przykład?

Albo nie umiem i nie działa, albo gdzieś popełniłeś błąd.

 

Cel to dostęp do klasy, która nas (klasę) stworzyła.

Czyli w plikach nagłówkowych klas: B i C nie mogę dołączać pliku nagłówkowego klasy A, ponieważ jej plik nagłówkowy dołącza pliki nagłówkowe klas B i C.

 

Czyli w tych plikach nie dam rady stworzyć zmiennej wskaźnikowej na klasę A.

A chcę wykorzystać właśnie funkcje tej klasy.

Więc potrzebna mi jej instancja klasy A wewnątrz klas B i C.

 

Odnośnie tego co mi napisałeś kodu to kompilator wypluwa mi błąd przy tworzeniu obiektu C:

 

c = new C(this);

 

odnośnie "Braku dopasowania funkcji dla wywołania C::C(A* const); "

rozumiem, że konwersję można spróbować zrobić ale też mi to nie chce działać.

 

Natomiast co do samego wskaźnika, to można w sekcji prywatnej klasy C stworzyć wskaźnik np. "void* baseClass;" i w konstruktorze przypisać:

this->baseClass = base;

 

po czym każdorazowe użycie dostępu do nadklasy :) wiąże się z takową wiązanką kodu:

A* aClass = static_cast<A>(this->baseClass);
//  aClass->b->test();

 

co można w prywatną funkcję obudować.

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

OK, dam przykład który wywala w konstruktorze klasy w pliku AClass.cpp z komunikatem:

no matching function for call to 'BClass::BClass(AClass* const)'|

this->bClass = new BClass(this);

A to całość:

main.cpp

#include "AClass.h"

int main()
{
   AClass* aClass = new AClass;

   delete aClass;
}

AClass.h

#ifndef ACLASS_H
#define ACLASS_H

#include "BClass.h"
#include "CClass.h"

class AClass
{
   public:
       AClass();
       virtual ~AClass();
       BClass* getBClass();
       CClass* getCClass();
   protected:
   private:
       BClass* bClass;
       CClass* cClass;
};

#endif // ACLASS_H

AClass.cpp

#include "AClass.h"

AClass::AClass()
{
   this->bClass = new BClass(this);
   this->cClass = new CClass(this);
}

AClass::~AClass()
{
   //dtor
}

BClass* AClass::getBClass();
{
   return this->bClass;
}

Class* AClass::getCClass();
{
   return this->cClass;
}

BClass.h

#ifndef BCLASS_H
#define BCLASS_H

class pAClass;

class BClass
{
   public:
       BClass(pAClass* _AClass_);
       virtual ~BClass();
       void testFunction();
   protected:
   private:
       pAClass* _aClass;
};

#endif // BCLASS_H

BClass.cpp

#include "AClass.h"

BClass::BClass(pAClass* _AClass_)
:_aClass(_AClass_)
{
   // this->_aClass = _AClass_;  /\ UP /\
}

BClass::~BClass()
{
   //dtor
}

void BClass::testFunction()
{
   std::cout << "test Function message";
}

CClass.h

#ifndef CCLASS_H
#define CCLASS_H


class pAClass;
class CClass
{
   public:
       CClass(pAClass* _AClass_);
       virtual ~CClass();
   protected:
   private:
       pAClass* _aClass;
};

#endif // CCLASS_H

CClass.cpp

#include "AClass.h"

CClass::CClass(pAClass* _AClass_)
:_aClass(_AClass_)
{
//  this->_aClass = _AClass_; /\ UP /\
  AClass* myClass = static_cast<AClass>(this->_aClass);
  myClass->getBClass()->testFunction();
}

CClass::~CClass()
{
   //dtor
}

 

To oczywiście przykład kodu zmodyfikowany na potrzeby metody "po Twojemu" :)

Moja wiedza na temat C++ nie jest wielka więc miło będzie się czegoś dowiedzieć

 

Pozdrawiam.

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

Z poprzednich Twoich wypowiedzi napisałeś:

class A;
class C
{
...

 

więc to jest zamiast "class A;"

Sam to zaproponowałeś.

Ps. średniki są na zakończenie instrukcji, co w tym złego? I proszę napisz gdzie widzisz nadmiar średników ?

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

A to wybacz proszę :]

Tak działa wszystko tak jak powinno, wystarczyło wspomnieć, że to ma być prototyp.

A o prototypach w C++ zapomniałem.

A średniki nie zauważyłem przy pisaniu, w pliku AClass.cpp jest nadmiar przy metodach getBClass() i getCClass().

Kod na szybko pisany.

 

 

 

 

Dzięki za pomoc.

Pozdrawiam.

Prawdziwy programista wiesza sie wraz ze swoim programem.

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...