Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

konstrukcja obiektu, którego składnikiem jest obiekt innej klasy

Ostatnio zmodyfikowano 2024-07-23 21:13
Autor Wiadomość
burn3ov
Temat założony przez niniejszego użytkownika
konstrukcja obiektu, którego składnikiem jest obiekt innej klasy
» 2024-07-21 16:04:31
Mamy grę snake z klasami Game, Tsnake i Tfood. Konstruktor Tsnake.h wygląda tak:

Tsnake( Tfood * f, Tdirection = Tdirection::right )


czyli wąż dostaje obiekt Tfood, którym się interesuje

zaś klasa Game tak:

C/C++
class Game
    : public Tsnake
    , Tfood
{
   
bool gameOver;
   
Tfood food;
   
Tsnake waz;
   
public:
   
Game();
   
void GetInput();
   
void Draw();
   
   
};

i teraz jak zainicjalizować obiekt Tsnake na liście inicjalizacyjnej klasy Game?
 
P-181346
DejaVu
» 2024-07-21 16:06:12
GPT 4o:
Aby zainicjalizować obiekt `Tsnake` na liście inicjalizacyjnej klasy `Game`, musisz skorzystać z listy inicjalizacyjnej w konstruktorze `Game`. Ponieważ konstruktor `Tsnake` przyjmuje wskaźnik do obiektu `Tfood` oraz opcjonalny argument typu `Tdirection`, musisz przekazać odpowiednie wartości w liście inicjalizacyjnej.

Zakładając, że masz odpowiednio zdefiniowane wartości dla `Tfood` i `Tdirection`, konstruktor klasy `Game` może wyglądać tak:

C/C++
class Game
    : public Tsnake
    , public Tfood
{
   
bool gameOver;
   
Tfood food;
   
Tsnake waz;
   
public:
   
Game()
        :
waz( & food, Tdirection::right ) // Inicjalizacja obiektu Tsnake na liście inicjalizacyjnej
   
{
       
gameOver = false;
   
}
   
   
void GetInput();
   
void Draw();
};

W powyższym przykładzie, obiekt `waz` typu `Tsnake` jest inicjalizowany przy użyciu obiektu `food` typu `Tfood` oraz wartości `Tdirection::right`. Lista inicjalizacyjna zapewnia, że obiekt `waz` jest poprawnie skonstruowany przed wykonaniem ciała konstruktora `Game`.

Jeśli `Tdirection::right` jest domyślną wartością w konstruktorze `Tsnake`, można go pominąć:

C/C++
class Game
    : public Tsnake
    , public Tfood
{
   
bool gameOver;
   
Tfood food;
   
Tsnake waz;
   
public:
   
Game()
        :
waz( & food ) // Inicjalizacja obiektu Tsnake na liście inicjalizacyjnej
   
{
       
gameOver = false;
   
}
   
   
void GetInput();
   
void Draw();
};

W ten sposób, obiekt `waz` zostanie poprawnie zainicjalizowany przy użyciu obiektu `food` bez potrzeby przekazywania drugiego argumentu, jeśli jego wartość domyślna jest wystarczająca.
P-181347
DejaVu
» 2024-07-21 16:09:01
W każdym razie macie jakiś dziwny koncept klasy Game, która dziedziczy po Tsnake i Tfood. Raczej czegoś nie zrozumieliście z dziedziczeniem i jego zastosowaniem, skoro takie konstrukcje robicie.
P-181348
burn3ov
Temat założony przez niniejszego użytkownika
» 2024-07-21 16:31:20
Faktycznie masz rację ta konstrukcja nie ma sensu o co innego mi chodziło. Zrobiłem wszystkie klasy i teraz chcę to wszystko jakoś scalić.  Aczkolwiek kompilator dalej wyświetla błąd:

Błąd C2512 "Tsnake": niedostępny odpowiedni konstruktor domyślny
P-181349
DejaVu
» 2024-07-21 16:40:16
Jedyne co da się napisać na podstawie tego co wkleiłeś, to: "kompilator napisał Ci jaki jest problem".
P-181350
tBane
» 2024-07-21 17:22:20
Po prostu nie dziedzicz po Tfood i Tsnake. I twórz instancje obiektów food oraz waz w konstruktorze gry

C/C++
class Game
{
   
bool gameOver;
   
Tfood food;
   
Tsnake waz;
   
public:
   
Game() {
       
food = Tfood();
       
waz = Tsnake();
       
gameOver = false;
   
}
   
   
void GetInput();
   
void Draw();
   
   
};
P-181351
burn3ov
Temat założony przez niniejszego użytkownika
» 2024-07-21 21:00:08
Dzięki właśnie o coś takiego mi chodziło. Jednak w książce mam taki zapis "Obiekt jakiejś klasy będący składnikiem innej klasy może być inicjalizowany jedynie za pomocą listy inicjalizacyjnej. Nie można próbować uruchomić konstruktora takiego obiektu składowego później, czyli z wnętrza konstruktora klasy, w której obiekt ten się zawiera. Wtedy jest już za późno" Czy to nie jest sprzeczne z zapisem powyżej?  
P-181352
pekfos
» 2024-07-21 22:35:03
Nie jest sprzeczne, bo to nie jest inicjalizacja, tylko przypisanie wartości po inicjalizacji. food i waz są inicjalizowane ich konstruktorami domyślnymi, a przypisania są nadmiarowe. Wystarczy tak:
C/C++
Game()
    :
gameOver( false ) // lub przypisaniem
{
}
Dla typów złożonych lepiej użyć listy inicjalizacyjnej, bo to jedno wywołanie konstruktora, a nie dwa plus kopiowanie.
P-181353
« 1 » 2
  Strona 1 z 2 Następna strona