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

Undefined reference to class...

Object Storage Arubacloud
0 głosów
433 wizyt
pytanie zadane 13 października 2022 w C i C++ przez Bilib Użytkownik (990 p.)

Witam! Rozważmy poniższe kody:

#include <iostream>
#include "klasa2.h"
using namespace std;
int main()
{
    klasa2 *kl2=new klasa2;
    kl2->wypisz();
    kl2->wypisz3();
    kl2->wypisz();
}
#ifndef klasa1_h
#define klasa1_h
#include<iostream>
using namespace std;
class klasa1
{
    public:
        string name;
};
#endif
#ifndef klasa2_h
#define klasa2_h
#include "klasa1.h"
#include "klasa3.h"
class klasa2
{
    public:
        klasa1 *obiekt=new klasa1;
        klasa2();
        void wypisz();
        void wypisz3();
};
#endif
#include "klasa2.h"
klasa2::klasa2()
{
    obiekt->name="Cześć";
}
void klasa2::wypisz()
{
    cout<<obiekt->name<<endl;
}
void klasa2::wypisz3()
{
    klasa3 *ob=new klasa3(obiekt);
    ob->wypisz();
    ob->set(obiekt);
}
#ifndef klasa3_h
#define klasa3_h
#include <iostream>
#include "klasa2.h"
using namespace std;
class klasa3
{
    public:
        klasa1 *ob=new klasa1;
        klasa3(klasa1 *obiekt);
        void set(klasa1 *obiekt);
        string str;
        void wypisz();
};
#endif
#include "klasa3.h"
klasa3::klasa3(klasa1 *obiekt)
{
    ob=obiekt;
    str="Elo";
}
void klasa3::set(klasa1 *obiekt)
{
    obiekt=ob;
}
void klasa3::wypisz()
{
    cout<<str<<endl;
    ob->name="Witam";
    cout<<ob->name<<endl;
}

Jest to uproszczony przykład mechaniki klas, które w różny sposób mają przekazywać i modyfikować pola i metody. Chcę to potem wykorzystać do większego projektu.

W programie Code::Blocks niby wszystko jest w porządku, wynik wyświetla się taki, jaki chciałem:

Cześć
Elo
Witam
Witam

Ale w Visual Studio Code terminal wyrzuca mi takie błędy dla pliku main.cpp:

undefined reference to `klasa2::klasa2()'
undefined reference to `klasa2::wypisz()'
undefined reference to `klasa2::wypisz3()'
undefined reference to `klasa2::wypisz()'

W którym miejscu popełniam błędy? Jakie to są błędy?

komentarz 14 października 2022 przez Oscar Nałogowiec (29,290 p.)

Pomijając fakt,  że w pliku Klasa3.cpp w linii 9 (metoda set) masz chyba podstawienie w drugą stronę, to błąd który wystąpił oznacza najczęściej, że niewłaściwie zostało wykonane linkowanie. Czegoś zabrakło. To dość typowe w sytuacji gdy program jest rozmieszczony w kilku plikach źródłowych. Normalnie utworzenie aplikacji składa się z kilku kroków - najpierw wszystkie pliki źródłowe (te *.cpp) należy skompilować do plików *.o lub *.obj a potem utworzone pliki połączyć w gotowy program linkerem. W środowiskach IDE najczęściej jest to automatyczne - jednak należy zdecydować, które pliki wchodzą w skład tzw. projektu. Jeśli pracuje się bez IDE to używa się albo prostego skryptu powłoki, albo narzędzia make i makefile do opisania zależności i procesu budowania aplikacji.

Być może Code::Blocks automatycznie dodaje do projektu wszystkie nowo utworzone pliki - stąd wie co zlinkować. W VS - jeśli po prostu otworzysz utworzony wczęśniej plik to za mało, trzeba jeszcze wskazać pozostałe pliki z jakich składa się projekt.

Nie używam żadnego z tych środowisk, więc nie mogą podać konkretnej instrukcji.

 

komentarz 14 października 2022 przez j23 Mędrzec (194,920 p.)

@Bilib, 

g++ -std=c++17 klasa2.cpp klasa3.cpp main.cpp -o klasa-app

komentarz 15 października 2022 przez Bilib Użytkownik (990 p.)

Bardzo wam dziękuję za odpowiedzi!

W przypadku VS Code wystarczyło w tasks.json dopisać brakujące pliki *.cpp (klasa2.cpp i klasa3.cpp), więc proces kompilacji powinien przebiegać mniej więcej tak jak zasugerował @j23.

Btw @Oscar, co do Klasa3.cpp, linia 9 - właśnie o to chodziło, żeby dokonać takiego podstawienia, ponieważ chcę trwale zmienić przekazaną z klasy klasa2 obiekt obiekt. Nie wiem czy jest to dobry sposób, może jest lepszy, ale w przypadku tego programu działa tak jak chciałem.

komentarz 16 października 2022 przez Oscar Nałogowiec (29,290 p.)
Dziwne, bo wskazana instrukcja nie robi nic, co by pozostawiło jakieś skutki po zakończeniu całej funkcji. Modyfikujesz parametr funkcji czyli zmienną tymczasową - w tym przypadku wskaźnik.
komentarz 16 października 2022 przez Bilib Użytkownik (990 p.)

W moim rozumieniu, obiekt jest tymczasową zmienną w klasa3, ale jest cały czas w klasa2 (tzn. póki sobie cały czas korzystam z kl2 w main.cpp). A ponieważ obiekt jest przekazywany do set przez wskaźnik a nie przez wartość, to obiekt ten jest trwale zmieniany (niekopiowany). Być może na pierwszy rzut oka sprawia to wrażenie jakby nic się nie stało, ale najpierw przekazuję do konstruktora ob=obiekt, czyli na razie ob->name=="Cześć", potem w wypisz zmieniam ob->name="Witam", na końcu w set obiekt=ob, czyli teraz w klasa2 obiekt->name=="Witam" - mniej więcej coś takiego.

komentarz 16 października 2022 przez Oscar Nałogowiec (29,290 p.)
Na szczęście informatyka to nauka doświadczalna. Możesz sprawdzić debuggerem co konkretnie się tam dzieje i jakie są skutki na zewnątrz funkcji.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
2 odpowiedzi 260 wizyt
pytanie zadane 7 stycznia 2023 w C i C++ przez mayak Nowicjusz (120 p.)
0 głosów
1 odpowiedź 104 wizyt
pytanie zadane 20 kwietnia 2018 w Java przez Sypni Nowicjusz (140 p.)
0 głosów
2 odpowiedzi 812 wizyt
pytanie zadane 2 grudnia 2015 w C# przez mrcnsct Nałogowiec (36,390 p.)

92,568 zapytań

141,422 odpowiedzi

319,637 komentarzy

61,957 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!

...