CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - każda klasa w oddzielnym pliku...

każda klasa w oddzielnym pliku...

dział ogólny

każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » wtorek, 10 października 2017, 00:21

Witam!
Do tej pory pisząc małe klasy na potrzeby zadań domowych z różnych książek, tworzyłem je w jednym pliku *.cpp.
Teraz chciałbym stworzyć kilka własnych klas dziedziczących z abstrakcyjnej klasy i napotkałem kilka niewiadomych.

Na przykład:
Abstrakcyjna klasa "zwierze" składa się z 2 plików: zwierze.h (deklaracje) oraz zwierze.cpp (definicje).
Jeśli jednak wszystkie funkcje będą czysto virtualne (czyli nie muszę umieszczać definicji tych funkcji dla klasy abstrakcyjnej) to po co mi plik: zwierze.cpp?
Czy wystarczy tylko plik z deklaracjami?

Następnie tworzę klasy pochodne, np.: pies, kot, ocelot. Rzecz jasna, że muszę mieć pliki: pies.h, kot.h, ocelot.h (deklaracje) oraz pies.cpp, kot.cpp, ocelot.cpp (definicje). Nie wiem jednak jak jest lepiej?
Czy prywatne składniki (które są wspólne dla wszystkich klas pochodnych) raz jeden umieścić w abstrakcyjnej klasie i nie powtarzać ich deklaracji w klasach pochodnych?
Czy może w klasie abstrakcyjnej nie umieszczać wcale składników, a umieścić je w klasach pochodnych mimo tego, że będą się powtarzały w klasie: pies, kot, ocelot?
Czy umieścić je wszędzie?

I ostatnie pytanie: jeśli includuję jakieś tam biblioteki, np: string czy cctype, to powinienem to zrobić w pliku: *.cpp?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » wtorek, 10 października 2017, 10:33

to po co mi plik: zwierze.cpp? Czy wystarczy tylko plik z deklaracjami?

Jeśli plik zwierze.cpp jest pusty, to odpowiedź nasuwa się sama. Ten podział na pliki .h i .cpp to nie jest dogmat. W przypadku małych klas czasami nie warto robić oddzielnego pliku źródłowego, wystarczy wszystko zrobić w jednym pliku nagłówkowym.

Czy prywatne składniki (które są wspólne dla wszystkich klas pochodnych) raz jeden umieścić w abstrakcyjnej klasie i nie powtarzać ich deklaracji w klasach pochodnych?

Tu także odpowiedź nasuwa się sama ;) Choć jeśli zależy Ci na "czystej" klasie-interfejsie, wtedy zrób klasę IZwierze, która zawiera tylko deklaracje metoda pure-virtual. Po niej niech dziedziczy np. ZwierzeBase, która zawiera pola i metody wspólne dla wszystkich potomków.

jeśli includuję jakieś tam biblioteki, np: string czy cctype, to powinienem to zrobić w pliku: *.cpp?

Tak by było najlepiej (ale nie zawsze się da).
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Arnold_S
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » wtorek, 10 października 2017, 17:44

Czyli rozumiem, że mogę np. zrobić to tak (najprościej jak się da):
Kod: Zaznacz cały
                                                       klasa abstrakcyjna zwierze
                                                       - prywatne składniki klasy (dzięki temu wpiszę je tylko raz)
                                                       - funkcje pure virtual (tylko deklaracje)
                                                       - wszystko umieszczę tylko w pliku zwierze.h
                                                      /                                             \
                                                    /                                                 \
                                                  /                                                     \
                                      klasa kot                                                     klasa ocelot
                             - funkcje wirtualne (def. i dekl.)                              - tak samo jak obok


Dzięki za podpowiedzi! Przyznam szczerze, że mam kilka kont na różnych forach ale TYLKO tutaj dyskusja jest kulturalna, odpowiedzi są rzeczowe i pomocne, bez owijania w bawełnę. Bardzo fajne jest to, że chcecie się dzielić swoją wiedzą. 8-)
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » wtorek, 10 października 2017, 18:44

Czyli rozumiem, że mogę np. zrobić to tak

Tak.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » sobota, 28 października 2017, 21:38

...ehhh nadal mam problem z tymi klasami abstrakcyjnymi.
Stworzyłem takie dwie małe klasy na potrzeby przykładu.

Klasa abstrakcyjna "zwierze" w jednym pliku ponieważ zawiera same deklaracje i jedną definicję.
KOD cpp:     UKRYJ  
#ifndef ZWIERZE_H
#define ZWIERZE_H

#include <cstdlib>  //rand();
#include <string>

class zwierze
{
public:
zwierze() {}
virtual ~zwierze() {}

enum rodzaj_kostki {K6, K10, K100};
unsigned short int rzut_kostka(rodzaj_kostki k);

virtual void losuj_uszy(void) = 0;
virtual void losuj_oczy(void) = 0;
virtual void losuj_futro(void) = 0;

virtual UnicodeString wyjmij_string(std::string &) = 0;
};

///////////////////////////////////////////////
unsigned short int zwierze::rzut_kostka(rodzaj_kostki k)
{
        unsigned short int y;
        if(k == K6)
        {       y = 1+(rand()%6);       }
        if(k == K10)
        {       y = 1+(rand()%10);      }
        if(k == K100)
        {       y = 1+(rand()%100);     }
        return y;      
}
#endif


Następnie stworzyłem klasę "kot", która składa się z dwóch plików kot.h i kot.cpp. Jak widać dziedziczy publicznie od abstr. klasy zwierze.
KOD cpp:     UKRYJ  
#ifndef KOT_H
#define KOT_H

#include <string>


class kot : public zwierze
{
private:
std::string     uszy, oczy, futro;
       
public:
kot()
{
        uszy = "nie wylosowano";
        oczy = "nie wylosowano";
        futro = "nie wylosowano";
}
virtual ~kot() {}

enum rodzaj_kostki {K6, K10, K100};
unsigned short int rzut_kostka(rodzaj_kostki k);

void losuj_uszy(void);
void losuj_oczy(void);
void losuj_futro(void);

UnicodeString wyjmij_string(std::string &);
};

#endif


Poniżej zawartość pliku z definicjami:
KOD cpp:     UKRYJ  
#include "kot.h"

void losuj_uszy(void)
{
        unsigned short int x = rzut_kostka(K6);
        if(x <= 3)      { uszy = "długie"; }
        else            { uszy = "krótkie"; }
}

void losuj_oczy(void)
{
        unsigned short int x = rzut_kostka(K10);
        if(x <= 3)                      { oczy = "czerwone"; }
        if(x > 3 && x <= 6)     { oczy = "szare"; }
        if(x > 6)                       { oczy = "niebieskie"; }
}

void losuj_futro(void)
{
        unsigned short int x = rzut_kostka(K100);
        if(x <= 33)                             { futro = "w czarne paski"; }
        if(x > 33 && x <= 66)   { futro = "w plamki"; }
        if(x > 66)                              { futro = "kot bez futra"; }   
}

UnicodeString wyjmij_string(std::string &cos)
{
        UnicodeString wynik = cos.c_str();
        return wynik;
}


W programie normalnie inkluduję te dwie klasy: #include "zwierze.h" i "kot.h". Forma zawiera button: "Losuj" oraz trzy pola Memo, w których pokazują się wylosowane wartości pobrane z wewnątrz klasy kot. Oto zawartość pliku unit1.cpp
KOD cpp:     UKRYJ  
#include <vcl.h>
#pragma hdrstop
#include <iostream>
#include "Unit1.h"
#include "zwierze.h"
#include "kot.h"
#include <ctime>          // dla time();
#include <cstdlib>   // dla srand();

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   srand(static_cast<unsigned int>(time(0)));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        kot dachowiec;
        zwierze *wsk = &dachowiec;

        wsk->losuj_uszy();
        wsk->losuj_oczy();
        wsk->losuj_futro();
        Memo1->Lines->Add(wsk->wyjmij_string(dachowiec.uszy));
        Memo2->Lines->Add(wsk->wyjmij_string(dachowiec.oczy));
        Memo3->Lines->Add(wsk->wyjmij_string(dachowiec.futro));
}


Wyskakuje mi komunikat, że E2247 'kot::uszy' is not accessible...wypaliło mi korki. Nie widzę błędu :( Wiem, że to podstawy podstaw ale idzie mi to nad wyraz pod górkę :(
Będę wdzięczny za każdą pomoc.
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » niedziela, 29 października 2017, 12:13

Poniżej zawartość pliku z definicjami:
KOD cpp:     UKRYJ  
void losuj_uszy(void) { ... }

void losuj_oczy(void) { ... }

void losuj_futro(void) { ... }

UnicodeString wyjmij_string(std::string &cos) { ... }

To są definicje funkcji, a nie metod klasy kot. Tak ma być:
KOD cpp:     UKRYJ  
void kot::losuj_uszy(void) { ... }

void kot::losuj_oczy(void) { ... }

void kot::losuj_futro(void) { ... }

UnicodeString kot::wyjmij_string(std::string &cos) { ... }

W wyjmij_string() argument cos powinien być const.



KOD cpp:     UKRYJ  
unsigned short int y;
if(k == K6)
{       y = 1+(rand()%6);       }
if(k == K10)
{       y = 1+(rand()%10);      }
if(k == K100)
{       y = 1+(rand()%100);     }
return y;  

Panie kolego, do takich rzeczy jest switch:
KOD cpp:     UKRYJ  
unsigned short int y;

switch(k)
{
case K6:    y = 1 + (rand() % 6); break;
case K10:   y = 1 + (rand() % 10); break;
case K100:  y = 1 + (rand() % 100); break;
}

return y;      

Prawda, że czytelniej?

Z drugiej strony można przecież to zredukować do:
KOD cpp:     UKRYJ  
enum rodzaj_kostki { K6 = 6, K10 = 10, K100 = 100 };
...

unsigned short int rzut_kostka(rodzaj_kostki k) { return 1 + (rand() % k); }




KOD cpp:     UKRYJ  
class kot : public zwierze
{
    ...      
public:
    ...

    enum rodzaj_kostki {K6, K10, K100};
    unsigned short int rzut_kostka(rodzaj_kostki k);
};

Dlaczego klasa kot definiuje swoje rodzaj_kostki i rzut_kostka()?



KOD cpp:     UKRYJ  
Memo1->Lines->Add(wsk->wyjmij_string(dachowiec.uszy));

Serio? Użycie wyjmij_string() ma być prostsze niż po prostu:
KOD cpp:     UKRYJ  
Memo1->Lines->Add(dachowiec.uszy.c_str());
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
Arnold_S
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » niedziela, 29 października 2017, 14:58

BARDZO dziękuję za cenne wskazówki!
...switch - no tak w prostocie siła :D
Funkcja "rzut_kostką" jest zdefiniowana raz w abstrakcyjnej klasie "zwierze". Czy to znaczy, że deklaracji (iż będę jej używał) nie muszę ponawiać w każdym nagłówkowym pliku, kolejnych klas potomnych, np: pies.h, opos.h, itd.?

Dlaczego klasa kot definiuje swoje rodzaj_kostki i rzut_kostka()?

Okej, to są publiczne sprawy klasy "zwierze" więc przy publicznym dziedziczeniu, są przekazywane dla potomka :D - dzięki, przeoczyłem to (brak doświadczenia i zez umysłowy).

Serio? Użycie wyjmij_string() ma być prostsze niż po prostu:
KOD cpp:     UKRYJ  
Memo1->Lines->Add(dachowiec.uszy.c_str());

Tworząc tą funkcję miałem bardziej na celu dostanie się do prywatnych składników klasy "kot" i tego samego w innych, np.: pies, opos, a nie prostotę użytkowania.
Zmieniłem kod według Twojego przepisu i nadal otrzymuję ten sam komunikat: [BCC32 Error] Unit1.cpp(32): E2247 'kot::uszy' is not accessible
Czy inkludując pliki nagłówkowe klas: zwierze i kot poprzez: #include "zwierze.h"...itd., to za mało? Muszę te pliki *.h i *.cpp dodać jakoś do projektu?

Mam jeszcze jedną wątpliwość: gdybym na przykład zechciał umieścić w klasie "kot" pryw.składniki: oczy, uszy i futro, w tablicy stringów, np.:
KOD cpp:     UKRYJ  
std:string tablica[3];

Funkcjami losuj_cośtam wypełniałbym pola tej tablicy ale jak miałbym przekazać tą wypełnioną tablicę na zewnątrz klasy, do swojego programu w XE2.
Musiałbym przeładować funkcję "wyjmij_string", tak aby przyjmowała tablicę...to raczej oczywiste, ale co miałaby zwracać abym wygodnie mógł wypełnić pola Memo1,2 i 3?
Myślę, że wewnątrz tej funkcji skopiowałbym zawartość tablicy stringów do lokalnie utworzonej tablicy obiektów UnicodeString i zwrócił wskaźnik do tej tablicy.
KOD cpp:     UKRYJ  
UnicodeString* wyjmij_string(const std::string &tab[], unsigned short int ile_pol)

Czy dobrze myślę?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » niedziela, 29 października 2017, 19:52

(...) i nadal otrzymuję ten sam komunikat: [BCC32 Error] Unit1.cpp(32): E2247 'kot::uszy' is not accessible

Przeoczyłem to, że uszy są prywatne (zasugerowałem się Twoim kodem).

Czy dobrze myślę?

No a klasyczne gettery nie wystarczą?
KOD cpp:     UKRYJ  
class zwierze
{
public:
        virtual size_t getTabSize() const = 0;
        virtual const std::string* getTab() const = 0;
        ...
};


class kot : public zwierze
{
private:
        std::string     tab[3];
       
public:

        size_t getTabSize() const { return 3; }
        const std::string* getTab() const { return tab; }
        ...
};


std::unique_ptr<zwierze> wsk = std::make_unique<kot>();

for(size_t i = 0; i < wsk->getTabSize(); ++i)
        Memo1->Lines->Add(wsk->getTab()[i].c_str());
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » niedziela, 29 października 2017, 21:04

/edit
Wydaje mi się i chyba się nie mylę, że funkcja "wyjmij_string" jest takim "getterem".
Mam tylko jedno pytanie. Co może powodować ten błąd E2247. Przecież funkcja "wyjmij_string" powinna mieć dostęp do prywatnych składników swojej klasy...a wygląda na to, że nie ma.
Ostatnio edytowano niedziela, 29 października 2017, 22:06 przez Arnold_S, łącznie edytowano 1 raz
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » niedziela, 29 października 2017, 21:43

Jak podajesz błąd, to podaj pełną treść. Co do pytania: tak, metoda powinna mieć dostęp do prywatnych pól swojej klasy. Bez przykładowego kodu lub wspomnianej pełnej treści błędu trudno coś konkretnego powiedzieć.


PS, gettery to nie są narzędzia, tylko zwykłe metody, które zwracają wartości niepublicznych pól klasy. Hint: getter, setter, accessor, mutator
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » niedziela, 29 października 2017, 22:12

Klasy "zwierze" i "kot" umieściłem na początku naszej ostatniej dyskusji. Oczywiście klasy poprawiłem tak jak zasugerowałeś.
Poniżej treść przykładowego programu w XE2:
KOD cpp:     UKRYJ  
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <iostream>
#include "Unit1.h"
#include "zwierze.h"
#include "kot.h"
#include <ctime>          // dla time();
#include <cstdlib>   // dla srand();

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
   srand(static_cast<unsigned int>(time(0)));
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        kot dachowiec;
        zwierze *wsk = &dachowiec;

        wsk->losuj_uszy();
        wsk->losuj_oczy();
        wsk->losuj_futro();
        Memo1->Lines->Add(dachowiec.wyjmij_string(dachowiec.uszy));
        Memo2->Lines->Add(dachowiec.oczy.c_str());
        Memo3->Lines->Add(dachowiec.futro.c_str());
}
//---------------------------------------------------------------------------


Treść błędu to:
[BCC32 Error] Unit1.cpp(32): E2247 'kot::uszy' is not accessible
Full parser context
Unit1.cpp(25): parsing: void _fastcall TForm1::Button1Click(TObject *)
[BCC32 Error] Unit1.cpp(33): E2247 'kot::oczy' is not accessible
Full parser context
Unit1.cpp(25): parsing: void _fastcall TForm1::Button1Click(TObject *)
[BCC32 Error] Unit1.cpp(34): E2247 'kot::futro' is not accessible
Full parser context
Unit1.cpp(25): parsing: void _fastcall TForm1::Button1Click(TObject *)
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » niedziela, 29 października 2017, 23:26

Ten błąd nie ma nic wspólnego z metodą wyjmij_string(), tylko z TForm1::Button1Click(), w której dobierasz się do prywatnych pół (oczy, uszy i futro) klasy kot.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » poniedziałek, 30 października 2017, 00:59

No niby tak...umieściłem to wyjmowanie w funkcji należącej do klasy TForm1 ale przecież staram się ją wyjąc przy pomocy funkcji należącej do klasy "kot". Nie mogę tak zrobić?
Czyli, żebym mógł legalnie operować funkcją "wyjmij_string" muszę zaprzyjaźnić funkcje klasyTForm1 z każdą klasą, np.: kot, pies, opos? Jakoś nie elegancko mi to wygląda...co jeśli będzie 100 buttonów? Czy może klasę abstrakcyjną i jej dziedziców umieścić wewnątrz klasy TForm1 jakby były jej obiektami? To zadziała?

/edit
W pliku zwierze.h i kot.h, w sekcji public, dodałem linijkę: :geek:
KOD cpp:     UKRYJ  
friend class TForm1;

Niestety w trakcie kompilacji pojawiają mi się błędy:
[ILINK32 Error] Error: Unresolved external 'kot::losuj_uszy()' referenced from C:\PROJEKTY\KLASY TEST\WIN32\DEBUG\UNIT1.OBJ
[ILINK32 Error] Error: Unresolved external 'kot::losuj_oczy()' referenced from C:\PROJEKTY\KLASY TEST\WIN32\DEBUG\UNIT1.OBJ
[ILINK32 Error] Error: Unresolved external 'kot::losuj_futro()' referenced from C:\PROJEKTY\KLASY TEST\WIN32\DEBUG\UNIT1.OBJ
[ILINK32 Error] Error: Unresolved external 'kot::wyjmij_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)' referenced from C:\PROJEKTY\KLASY TEST\WIN32\DEBUG\UNIT1.OBJ
[ILINK32 Error] Error: Unable to perform link
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez polymorphism » poniedziałek, 30 października 2017, 11:56

(...) ale przecież staram się ją wyjąc przy pomocy funkcji należącej do klasy "kot".

Mówisz o tym:
KOD cpp:     UKRYJ  
Memo1->Lines->Add(dachowiec.wyjmij_string(dachowiec.uszy));

:?: Przecież tutaj odwołujesz się do prywatnego pola kot::uszy z wnętrza metody, która nie wchodzi w skład klasy kot. To oczywiste, że masz błąd. Pokazałem Ci, jak powinien wyglądać dostęp do prywatnych pól klasy przy użyciu publicznych akcesorów/getterów.

W 99% przypadków nie ma potrzeby zaprzyjaźniania klas. Twój przypadek zdecydowanie nie należy do tego 1%.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows 7Firefox

Re: każda klasa w oddzielnym pliku...

Nowy postprzez Arnold_S » poniedziałek, 30 października 2017, 19:47

Jeśli chodzi o std::unique_ptr to chyba nie wypali ponieważ Builder XE2 nie obsługuje nawet C++11 ...a co dopiero C++14.
Poczytam, może na coś wpadnę. Czy jeśli buduję własną klasę pod ten builder, to czy deklaracje funkcji muszę ubierać w konwencje wywołania: __fastcall ?
Avatar użytkownika
Arnold_S
Homos antropiczny
Homos antropiczny
 
Posty: 58
Dołączył(a): niedziela, 12 czerwca 2016, 23:22
Podziękował : 15
Otrzymał podziękowań: 0
System operacyjny: Win7 64b
Kompilator: C++ Builder 6, Rad Studio XE2
Gadu Gadu: 0
    Windows 7Firefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 54 gości

cron