Šta je novo?

C++ greska pri linkovanju...?

nexilion

Slavan
Učlanjen(a)
14.08.2007
Poruke
403
Poena
319
Kod:
//student.h

class Student {
  char* ime;           // Ime studenta.
  long  ind;           // Broj indeksa
  int*  ocene;         // Niz ocena.
  int   kap, brOc;     // Kapacitet niza i broj ocena.
  Student (const Student&) {}         // Ne sme da se kopira.
  void operator= (const Student&) {}  // Ne sme da se dodeljuje.
public:
  Student (char* iime, long iind, int kkap=40);

  Student promeniIme(const char* iime);
  ...

Kod:
//student.cpp
#include "student.h"
#include <cstring>
#include <cstdlib>
using namespace std;

Student::Student (char* iime, long iind, int kkap) {
  ime = new char [strlen(iime)+1];
  strcpy (ime, iime);
  ind = iind;
  ocene = new int [kap = kkap];
  brOc = 0;
}

Student Student::promeniIme(const char *iime)
{
	delete [] ime;
	ime = new char[strlen(iime)+1];	//+1 ostavljamo mesta za /0
	strcpy(ime, iime);
	return *this;
}
...

Pri kompajliranju jedna greska: "1>studentt.obj : error LNK2019: unresolved external symbol "public: __thiscall Student::Student(char const *,long,int)" (??0Student@@QAE@PBDJH@Z) referenced in function _main
1>E:\Projekti\C++ Projekti\zad3.6\Debug\zad3.6.exe : fatal error LNK1120: 1 unresolved externals"

Kada stavim da bude: Student (const char* iime, long iind, int kkap=40); i naravno u cppu isto, onda radi bez problema. Dok funkcija promeniIme, radi i sa i bez const.

Zasto tako, sta je problem? I koja je razlika izmedju [znam da const pod a) kaze da necemo menjati parametare, a const u b)?]:
a) Funkcija(const param1, const param2){};
b) Funkcija(param1, param2) const {};
 
Sa ovim const kod pokazivaca sprecava da promenis pokazivac i izgubis vezu sa podatkom.

b) znaci da je funkcija konstantna, to jeste, ne menja nista, samo cita.
 
Poslednja izmena:
Da, tako nesto...

b) znaci da se ni jedan atribut klase kojoj pripada ta metoda ne menja. Uloga tog const-a je da kaze kompajleru da moze da primeni neke optimizacije pri prevodjenju.

Kada const stoji uz neki argument metode to znaci da se taj argument ne menja u toj metodi. Ti si verovatno probao da neki konstantni pokazivac na string prosledis metodi koja prima obican pokazivac, pa se linker buni jer te dve metode imaju razlicite potpise.
 
Laslo Kraus vozi apstraktni auto.. 😀
 
Dobro ste prepoznali 🙂
Osim ovoga sto sam vec napisao (definicije konstruktora u cpp fajlu), jedino mesto gde se jos taj konstruktor koristi je u main-u:

Kod:
int main () {

  cout << "n: ";
  int n; cin >> n;

  Student** s = new Student* [n];
  for (int i=0; i<n; i++) {

    char ime[50]; long ind; cin >> ime >> ind;
    Student* t = new Student (ime, ind);
    int brOc; cin >> brOc;

    for (int j=0; j<brOc; j++) { int oc; cin >> oc; *t += oc; }

Sta mu odavde moze smetati? Nikako da provalim, a linker koliko je recit, cak ni liniju koda nece da mi kaze:crash:...
-----------------------------------------------
EDIT:

Nasao sam gde ga zeza:
Kod:
    char ime[50]; long ind; cin >> ime >> ind;
    [B]Student* t = new Student (ime, ind);[/B]

Kad ovo iskomentarisem, ne javlja gresku. Greska se javlja na: Student* t = new Student (ime, ind);
Probao sam da umesto char ime[50] stavim samo char* ime ali ni to ne pomaze, samo sam dobio warning da pokusavam neinicijalizovanu promenljivu ime da koristim. To je u Visual C++ 2008.
A evo sta kaze na to G++ kompajler: C:\Users\N\AppData\Local\Temp/cccYsMFo.o:studentt.cpp🙁.text+0x22b): undefined reference to `Student::Student(char*, long, int)'
collect2: ld returned 1 exit status


Sta mu to smeta, sta je razlog?
 
Poslednja izmena:
Pogledao sam na briznu, mislim da je problem sto ti imas konstruktor koji prima 3 promenljive, a ti saljes samo 2. Probaj ili ovako da pravis objekat

Student* t = new Student (ime, ind,0);

ili dodaj u konstruktoru

Student::Student (char* iime, long iind, int kkap=0) {
...

ili napravi konstruktor koji prima samo te 2 promenljive.

Nadam se da je to to. Poz
 
U header fajlu konstruktor je deklarisan vec tako:
Student (char* iime, long iind, int kkap=40);

Ako bih to stavio i u cpp fajl taj defaul parametar, onda bi to bila greska redefinisanje default parametra.


Medjutim, kad se pozove iz maina kao sto si rekao: Student* t = new Student (ime, ind,40); to radi! Zasto je tako (posto vec ima default parametar a i ono const ne stoji uz taj parametar)? Izgleda savim ok kod kad se pogleda i ne prijavljuje nikakvu gresku, tek linker uspe da zbuni...

I sad vratio sam sve u pocetno stanje i pozvao na stari nacin i ocistio Solution (da bi rebuildovao sve od pocetka) i kad sam pokrenuo sve je radilo:bottle:, sa onim starim sourceom koji mi do sinoc nije radio.... Kao da mu se razjasnilo nesto... I sad komotno kompajlira onaj kod gde je linker javljao gresku:zgran::zgran::zgran:
Kako sad to...?
 
Poslednja izmena:
Uzivaj. Ja bas ovih dana spremam OOP i preko glave su mi takve gluposti. Potpuno sam batalio da idem na build vec samo rebuild 🙂. Cek da stignes do template-a, tu ces da uzivas :d .
 
Pa ako ste na ETF-u obojca, uzivajte sada, dok jos mozete, uz OOP. Videcete u sledeca dva semestra sta je muka dok budete radili projekte iz operativnih sistema 1 i 2.

Sto se tice zadatka, negde drugde ti pravis gresku.

Ovo, na primer, ovo prolazi bez problema:

Kod:
#include <iostream>
#include <string>

using namespace std;


class Student {
private:
	char* _name;

public:
	Student(char* name) {
		_name = new char[strlen(name) + 1];
		strcpy(_name, name);
	}

};

int main() {	
	char c[50];
	cin >> c;
	Student s(c);
}
 
Ja sam u Nisu, racunarstvo i informatika na elektronskom. Ali izgleda da se plan i program poklapa u ovom delu (posto i mene cekaju OS-evi samo nisam siguran da li narednog ili onog tamo semestra.
 
Poslednja izmena:
Nazad
Vrh Dno