Glupost! Sto tocno u DevC++-u ne radi kako bi trebalo. On jeste zastario, ali previse ga kudite.
Nije se razvijao od 2005 i zato pretpostavljeno dolazi sa prastarom verzijom gcc-a 3.2 (aktualna 4.7) i gdb-a.
Glupost! Sto tocno u DevC++-u ne radi kako bi trebalo. On jeste zastario, ali previse ga kudite.
Nije se razvijao od 2005 i zato pretpostavljeno dolazi sa prastarom verzijom gcc-a 3.2 (aktualna 4.7) i gdb-a.
Glupost! Sto tocno u DevC++-u ne radi kako bi trebalo. On jeste zastario, ali previse ga kudite.
Nije se razvijao od 2005 i zato pretpostavljeno dolazi sa prastarom verzijom gcc-a 3.2 (aktualna 4.7) i gdb-a.
Ali ipak je dovoljan za početnike.
dolazi sa prastarom verzijom gcc-a
Da, ali to nije bitno početniku. On tek treba da se upozna sintasku jezika i način razmišljanja programera. Ja mu nisam preporučio DevCpp, neka ide na C::B ili Visual C++, ali sam mišljenja da i ako kojim slučajem krene sa DevCpp-om neće "lošije" shvatiti logiku. IDE je manje važna stvar za početnike, njihovi programčići imaju do cca 20 linja kôda i to možeš kucati u običnom tekst editoru tipa N++.
Dali zna ko rabit sa GOCR library da iz slike iscita slova i brojke u c++
Glupost! Sto tocno u DevC++-u ne radi kako bi trebalo. On jeste zastario, ali previse ga kudite.
Ma jede djecu, tuče pse, uvodi bugove u kod koji je u njemu nakucan, od puno tipkanja u DevCpp-u bole prsti, itd...
Sta su to static varijable tj. cemu sluze?
Kod funkcija svakim pozivom istih sve varijable se postave na početne vrjednosti ili smeće, ponekad to ne želimo, ako želiš da pri sljedećem pozivu te funkcije neka varijabla ima vrijednost koju je imala prije tog poziva, tj. da se ne "resetuje", označit ćeš tu varijablu kao statičnu. Ključnom riječi static.
Sta su to static varijable tj. cemu sluze?
Ovisi gdje su definirane. @royalhero ti je vec pojasnio kada je staticka varijabla definirana u funkciji. No ona moze biti definirana i u globalnom podrucju. Tada znaci da ta varijabla nalazi samo u datoteci(modulu) u kojem je definirana. Kada imas kod u vise datoteka, i ako ti u jednoj definiras neku globalnu varijablu, onda globalna varijabla vrijedi u svim datotekama koje je ukljucuju, i ti ne smijes vise imati varijabla koje imaju isto ime kao ta globalna. No ako je ona staticka onda ona samo vrijedi u toj datoteci u kojoj je deklarirana. Konstante globalne varijable se automatski deklariraju kao staticke, no ti ih pomocu kljucne rijeci extern mozes uciniti nestatickima.
Staticke varijable mogu biti i u klasama, i tu imaju vrlo slicnu ulogu kao u funkcijama. One su zajednicke za sve instance te klase, pa ako pomocu jednoga objekta te klase postavis neku vrijednost toj varijabli, onda ako s drugim objektom te klase pristupas toj varijabli, vrijednost ce biti ona koju si postavio u drugome objektu. Da bi pristupio statickim varijablama neke klase, izvan tog objekta(pod uvjetom da je pravo pristupa javno) ti uopce ne moras stvarati objekt vec mozes direktno preko imena klase pristupiti tome objektu po principu: imeklase::imevarijable. Postoje jos i staticke funkcije unutar klase, a to su funkcije koje samo pristupaju statickim clanovima. Oni se jos razlikuju po tome sto ne moras uopce imati niti jednu instancu klase da bih pozvao vec ih jednostavno pozivas po principu: imeklase::imefunkcije:
#include <iostream>
using namespace std;
//klasa sa statickim clanom
class test{
private:
//Privatna staticka varijabla kojoj zboga prava
//pristupa ne mozemo direktno pristupati pa
//moramo koristiti funkcije
static int a;
public:
//Staticke get() i set() funkcije za pristupanje
//statickome clanu
static int get();
static void set(int);
};
//Prije nego sto probamo pristupiti clanu moramo ga
//inicijalizirati i to uvijek radimo na ovaj nacin
//izvan klase.
int test::a = 0;
//Definicija get() i set() funkcija
//Ne navodimo kljucnu rijec static jer se ona samo
//navodi u deklaraciji funkcija
int test::get(){
return a;
}
void test::set(int x){
a = x;
}
int main(){
//ispisujemo staticki clan klase test pomocu get funkcije
cout<<test::get()<<endl;
//mijenjamo vrijerijednost statickog clana pomocu set funkcije
test::set(10);
//ispisujemo novu vrijednost
cout<<test::get()<<endl;
return 0;
}
//primjeti da iako pristupamo clanu klase, nigdje nismo
//kreirali niti jedan objekt te klase
Imam pitanje u vezi privremenih objekata:
#include <iostream>
class vector{
friend void addVectors(vector &a, vector &b, vector &c);
private:
static int numObjects;
double ax,ay;
int num;
public:
vector(double x=0,double y=0):ax(x),ay(y),num(++numObjects){
std::cout<<"Vector "<<num<<" created."<<std::endl;
}
vector(const vector& copy):ax(copy.ax),ay(copy.ay),num(++numObjects){
std::cout<<"Vector "<<copy.num<<" copied into vector "<<num<<std::endl;
}
~vector(){
std::cout<<"Vector "<<num<<" destroyed."<<std::endl;
}
double getX(){return ax;}
double getY(){return ay;}
void set(double x, double y){ax = x; ay=y;}
};
int vector::numObjects = 0;
void addVectors(vector &a,vector &b,vector &c){
c.ax = a.ax + b.ax;
c.ay = a.ay + b.ay;
}
int main(){
vector c;
addVectors(vector(),vector(),c);
return 0;
}
Male mi probleme stvara ova funkcija addVectors jer mi g++ prikaze error:
object_2.cpp:32:32: error: invalid initialization of non-const reference of type ‘vector&’ from an rvalue of type ‘vector’
object_2.cpp:26:6: error: in passing argument 1 of ‘void addVectors(vector&, vector&, vector&)’
Jasna mi je poruka kompajlera da vector() nije konkrenta lvrijednost vec rvrijednost i ne bi se smjela pridruzivati referenci. No po demistificiranom C++-u ovo bi trebalo raditi jer ce stvoriti privremeni objekt i onda proslijediti adresa toga objekta funkciji. Moze li mi netko pojasniti u cemu je problem?
Imam pitanje u vezi privremenih objekata:
#include <iostream>
class vector{
friend void addVectors(vector &a, vector &b, vector &c);
private:
static int numObjects;
double ax,ay;
int num;
public:
vector(double x=0,double y=0):ax(x),ay(y),num(++numObjects){
std::cout<<"Vector "<<num<<" created."<<std::endl;
}
vector(const vector& copy):ax(copy.ax),ay(copy.ay),num(++numObjects){
std::cout<<"Vector "<<copy.num<<" copied into vector "<<num<<std::endl;
}
~vector(){
std::cout<<"Vector "<<num<<" destroyed."<<std::endl;
}
double getX(){return ax;}
double getY(){return ay;}
void set(double x, double y){ax = x; ay=y;}
};
int vector::numObjects = 0;
void addVectors(vector &a,vector &b,vector &c){
c.ax = a.ax + b.ax;
c.ay = a.ay + b.ay;
}
int main(){
vector c;
addVectors(vector(),vector(),c);
return 0;
}
Male mi probleme stvara ova funkcija addVectors jer mi g++ prikaze error:
object_2.cpp:32:32: error: invalid initialization of non-const reference of type ‘vector&’ from an rvalue of type ‘vector’
object_2.cpp:26:6: error: in passing argument 1 of ‘void addVectors(vector&, vector&, vector&)’
Jasna mi je poruka kompajlera da vector() nije konkrenta lvrijednost vec rvrijednost i ne bi se smjela pridruzivati referenci. No po demistificiranom C++-u ovo bi trebalo raditi jer ce stvoriti privremeni objekt i onda proslijediti adresa toga objekta funkciji. Moze li mi netko pojasniti u cemu je problem?
trebalo bi uvesti 2 objejekta u igru , npr a i b.
#include <iostream>
class vector{
friend void addVectors(vector &a, vector &b, vector &c);
private:
static int numObjects;
double ax,ay;
int num;
public:
vector(double x=0,double y=0):ax(x),ay(y),num(++numObjects){
std::cout<<"Vector "<<num<<" created."<<std::endl;
}
vector(const vector& copy):ax(copy.ax),ay(copy.ay),num(++numObjects){
std::cout<<"Vector "<<copy.num<<" copied into vector "<<num<<std::endl;
}
~vector(){
std::cout<<"Vector "<<num<<" destroyed."<<std::endl;
}
double getX(){return ax;}
double getY(){return ay;}
void set(double x, double y){ax = x; ay=y;}
} a , b; // iniciraj 2 vektora
int vector::numObjects = 0;
void addVectors(vector &a,vector &b,vector &c){
c.ax = a.ax + b.ax;
c.ay = a.ay + b.ay;
}
int main(){
vector c;
// a i b su u igri
addVectors(/*vector(),vector()*/ a , b , c);
return 0;
}
Meni je sve to jasno. Sada imamo 2 konkrenta objekta i mozemo proslijediti njihove adrese. No to nije ono sto pitam.
Poziv:
addVectors(vector(),vector(),c);
bi po Demistificiranom C++-u trebao raditi kao i onaj sa objektima, jer se ovako prvo stvararu privremeni i njihova se adresa prosljeduje, a nakon zavrsetka funkcije njihovo postojanje prestaje. Ovaj princip prikazuju u Demistificiranom C++-u , no meni kompajler prikazuje error. Mene zanima zasto je tako? Je li to greska u demistificarnom c++-u ili je mojim postavkama kompajlera?
Privemeni objekti imaju kratki vijek trajanja pa se zato može reći da je pogrešno prosljeđivati njihove reference drugim funkcija. Možda je to bilo dostupno u toj verziji compilera u vrijeme kad je knjiga pisana no danas očito nije (ne podržava niti moj C++ Builder compiler).
Umjesto toga, privremeni objekti se najčešće koriste kao povratne vrijednosti funkcija. Npr.;
Kompleksni operator + (const Kompleksni &Z1, const Kompleksni &Z2){
return Kompleksni(Z1.re + Z2.re, Z1.im + Z2.im);
}
ili pri samoj inicijalizaciji objekata;
Kompleksni polje[3] = { Kompleksni(1,1), Kompleksni(1,2), Kompleksni(2,1) };
Ok. No je li u redu prosljedivati privremene objekte po vrijednosti funkcijama? Pa npr. da promijenim funkciju addVectors u:
void addVectors(vector pribrojnik1,vector pribrojnik2,vector& rezultat);
Tada bih mogao prosljedivati privremene objekte:
addVectors(vector(13,14),vector(),c);
Po pravilu buduci da ove pribrojnike prosljedujemo po vrijednosti, ovi privremeni objekti bi se konstruktorom kopije trebali kopirati novostvorene objekte i onda bi ti bili prosljedeni funkciji. No ovdje compiler prepozna da se radi o privremenim objektima i napravi optimatizaciju pa posalje vec napravljene privremene objekte. Dakle dobivamo isti efekt kao da prosljedujemo reference na privremene objekte.
No situacija je malo drugacija kada saljemo objekte koji nisu privremeni. Poziv:
addVectors(a,b,c);
bi prouzrocio da se objekti a i b konstruktorom kopije kopiraju u novostvorene objekte i onda bi se ti objekti proslijedili funkciji. To, osim sto nepotrebno oduzima vrijeme, nepotrebno oduzima i memoriju jer u jednome trenutku imamo 5 objekata klase vector.
Kada ih prosljedujemo kao referencu onda ne bismo imali takve gubitke na vremenu i memoriji. No onda ne bih mogao slati privremene objekte vec bi morao stvoriti zasebno objekte koje bi proslijedio i funkciji, no to je trosenje resursa jer cu te objekte koristiti samo jednom za slanje toj funkciji.
Ovdje mi se najlogicnije cini da potpuno izbjegavam situacije u kojima bih trebao proslijediti privremeni objekt(i kao referencu i po vrijdenosti). Je li to dobro rjesenje?
Imam pitanje,znaci ako je std klasa,ako ne koristis namespace std; onda moras pisati naprimjaer std::cout i sad ja napravim klasu klasa,dodam joj javnu varjablu a,ako je ja zelim koristiti izvan klase trebam napisati klasa::a,a ako stavim namespace klasa; i napisem a imam error.
Znaš li uopće što je namespace?
Da znam citao sam u jednoj knizi,on se definira kao: namespace ime?
Znaci std nije klasa vec namespace.
Ovdje mi se najlogicnije cini da potpuno izbjegavam situacije u kojima bih trebao proslijediti privremeni objekt(i kao referencu i po vrijdenosti). Je li to dobro rjesenje?
S privremenim objektima treba biti jako oprezan a pogotovo još kada su reference u pitanju jer se može dogoditi da je najednom riječ o referenci na nešto što više ne postoji (kao u slučaju vraćanja reference lokalnog objekta funkcije). Najbolje je koristiti ono već isprobano tj. call by value ili call by reference (adrese već postojećih objekata a ne privremenih).
Da, namespace je tu radi organizacije, recimo, možeš imati više funkcija sa različitim imenom u više namespace-a.
Čitaj malo tu:
http://www.cplusplus.com/doc/tutorial/namespaces/
Imam pitanje,znaci ako je std klasa,ako ne koristis namespace std; onda moras pisati naprimjaer std::cout i sad ja napravim klasu klasa,dodam joj javnu varjablu a,ako je ja zelim koristiti izvan klase trebam napisati klasa::a,a ako stavim namespace klasa; i napisem a imam error.
Imenik (eng. namespace) i klasa su dvije razlicite stvari. Imenik oznacava skup odredenih varijabli, funkcija i drugih objekata. Naime u odredenim velikim aplikacijama cesto se dogada da one ukljucuju mnogo vanjskih biblioteka i zato se lako moze dogodotiti da se u dva razlicitia modula nalaze npr. dvije funkcije koje imaju isto ime. To uzrokuje mnoge probleme i to se mora na neki nacin rijesiti. U c-u nisu postojali imenici pa se to rjesavalo vrlo nezgodno u indetifikatorima, pa bi se ispred imena funkcije, strukture i sl. dodalo neko ime + _. Npr. SDL_show(), SDL_count() i sl. U c++/u to se rjesava pomocu imenika koji se deklariraju na nacin:
namespace ime_imenika{
//objekti koje imenik sadrzi
}
I ako trebas nesto iz toga imenika onda se koristis sintaksom: ime_imenika::ime_objekta. Pa bi funkcija SDL_show() u c++ stilu bila: SDL::show().
Kod klasa sintaksa klasa::ime_objekta funkcionira jedino u slucaju kada je objekt kojemu pristupas deklariran kao statican, u ostalim slucajevima to nije moguce, jer nestaticki objekti postoje samo u istanci neke klase i to su za svaku instancu razliciti. Njima pristupas po principu imeinstance.imeobjekta(varijable). No mozes i koristiti i puno ime: imeinstance.imeklase::imeobjekta. No bitno je shvatiti da je to specificno za svaku instancu:
class mnogokut{
private:
int brojStrana;
}
int main(){
mnogokut trokut,cetverokut;
trokut.brojStrana = 3;
cetverokut.brojStrana = 4;
}
U ovome primjeru vidis da brojStrana kod cetverokuta i trokuta se razlikuju iako pripadaju istoj klasi mnogokut.
Ne mozes klase koristiti samo za grupiranje objekata, za to se koriste imenici.
Imam pitanje,znaci ako je std klasa,ako ne koristis namespace std; onda moras pisati naprimjaer std::cout i sad ja napravim klasu klasa,dodam joj javnu varjablu a,ako je ja zelim koristiti izvan klase trebam napisati klasa::a,a ako stavim namespace klasa; i napisem a imam error.
Ma napravi novu datoteku u projektu i nazovi je Klasa.h, u njoj deklariraj klasu Klasa
Zatim u npr. main.cpp u zaglavlju napiši include "Klasa.h"
Sad ideš standardnom procedurom:
Klasa klasa; // instanca klase
klasa.a = 5; // pristup podatkovnom, članu klase preko instance klase
A javnim članovima klase možeš ići sada i ovako:
Klasa::Metod();
Zato sto je u slucaju imeklase::objekt to staticki objekt. To sam ti objasnjavo par postova iznad. A kad koristimo novoime.objekt onda pristupamo nestatickim objektima tj. onima koji su specificni za svaku instancu.
Kapetan, javnim članovima i nestatičke klase koji i sami nisu static, možeš pristupiti pomoću klase, razlog je defincija članova izvan klase.
(ako sam ovdje što pogriješio neka @Tracer ispravi, da ne bi bilo zabune)
A javnim članovima klase možeš ići sada i ovako:
Klasa::Metod();
Mozes pod uvjetom da clan(varijabla, funkcija) staticka, a ako nije onda moras imati instancu.
Kapetan, javnim članovima i nestatičke klase koji i sami nisu static, možeš pristuoti pomoću klase, razlog je defincija članova izvan klase.
Mislim da to nije tocno. Ako je neka varijabla nestaticna onda je ona specificna za svaku instancu objekta i ne mozes samo prako klase pristupati tome clanu, treba ti instanca. Te nestaticke varijable uopce ne smijes ni inicijalizirati bez kontruktora (iznimka je novi c++11 standard koji dopusta da se tako postavi defaultna vrijednost neke varijable). A sto se tice tice nestatickim metoda, one su nestaticke metode zato sto mijenjaju nestaticke clanove koji su specificni za svaku instancu, pa ih ne mozes pozivati preko instance. U svakom slucaju za nestaticke clanove treba ti instanca jer bi po tvojoj logici ovo pod zuto bilo moguce:
#include <iostream>
using namespace std;
class test{
public:
int a;
void set(int);
};
void test::set(int x){a=x;}
int main(){
test::set(5);
cout<<test::a<<endl;
return 0;
}
Za žuto si u pravu, međutim, u globalnom području si definirao tijelo metoda set baš na taj način.
Dakle, moj ispravak, nestatičke metode je moguće preko klase definirati u globalnom području.
Ne <klasa.h>, nego "klasa.h".
Kad napravim header sa klasom i include-am ga,pise "No such file or directory".
Ti pišeš:
#include <klasa.h>tj. naziv headera okruzuje sa < >, a time govoris prevoditelju da je to standardni header. Umjesto toga header moras okruziti sa ":
#include "klasa.h"