» »

[C++] prevajalnik hoce konstruktor za strukturo

[C++] prevajalnik hoce konstruktor za strukturo

atasmrk ::

Jaz sem izcrpal svoje znanje tega jezika. Nekako mi ni jasno, kaj je v tem kosu kode lahko narobe.

najprej Object.h

#define MAX_VERTEX_COUNT 2000
#define MAX_POLYGON_COUNT 2000

typedef struct
{
		float x;
		float y;
		float z;
		
}VERTEX;

typedef struct
{
		int a; 
		int b;
		int c;

}POLYGON;

typedef struct
{
	VERTEX vertices[MAX_VERTEX_COUNT];
	POLYGON polygons[MAX_POLYGON_COUNT];
	
}OBJECT;


potem pa se uporaba teh struktur v main.cpp

OBJECT cube;
cube.vertices[0].x = -10;
cube.vertices[0].y = -10;
cube.vertices[0].z = 10;


in tako naprej za vsa preostala ogljisc kocke. Mi kdo ve povedat, zakaj prevajalnik vrze "expected constructor, destructor or type conversion before '.' token"? Prevajalnik je MinGW, uporablja pa ga DevC++ v Win32.

Pa se ena stvar. Malo me moti tisti #define MAX_VERTICES_COUNT 2000. Veste za kaksen bolj pameten nacin generiranja tabele (recimo z malloc vem da se da generirati tabelo int-ov, tako da potem sploh ne ves, da je to dinamicno generirana tabela. Ne vem pa, kako se to obnese s tabelo struktur)
  • spremenilo: atasmrk ()

OwcA ::

To kar ti pišeš ni ravno C++.

V C++ je struct bolj ali manj enakovreden class-u (samo privzet dostop do atributov je drugačen), zato ga tudi tako uporabi.
struct VERTEX
{
...
};

dokler imaš konstantne vrednosti je namesto #define lepše uporabiti navadno spremenljivko s kvalifikatorjem const:
const unsigned int MAX_VERTEX_COUNT = 2000;

Druga rešitev bi seveda bilo dinamično alociranje, ki pa se v C++ večinoma naredi z operatorjema new in delete, oziroma new[],delete[] za polja.


[edit - dodal eno malenkost - vsc]
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenil: Vesoljc ()

atasmrk ::

OwcA, naredil sem po tvojem predlogu (namesto C pisal C++, saj je bilo to narobe, ne), pa se stvar ni cisto nic spremeinla. Stanje tudi ni cisto nic boljse, ce imam vse deklaracije v enem .cpp fajlu. Malo se mi ze trapasto zdi vse skupaj.

Gundolf ::

Če jaz kodo copy pastam v visual studio (vse skupaj v en fajl) se mi prevede.
Premalo informacij si nam dal. Pa si pogledal v keri vrstici je error, da ni morda nekje čisto drugje?

atasmrk ::

No, ja nisem vam povedal, kje se napaka pojavi. Napako javi v vrstici

cube.vertices[0].x;

in v vseh naslednjih, ki imajo opraviti z ogljisci in poligoni kocke. Tudi ce napisem

cube = 10;

ali kaj podobno napacnega, je vrnjeni error enak, malo se zaradi operatorjev spremeni besedilo.

Se pa ravno zacenjam ucit OpenGL. Na NeHe sm pobral kodo za okna odpirat, na spacesim.net pa tele definicije ogljisc in poligonov. Tam na spacesim.net uporabljajo glut knjiznice, na NeHe pa glaux. Mogoce bi bilo kaj zaradi mesanja ampak sem zelo skepticen glede tega. Koneckoncev lahko zakomentiram include od teh dveh knjiznic, pa bo se vedno vse delalo, kot je treba (ce zakomentiram kocko jasno). Kako vam se lahko pomagam, da mi boste lahko pomagali?

Gundolf ::

Lahko poskusiš preimenovati ta dva structa. Mogoče si s pobrano kodo skopiral kakšen nadležen makro in te zdaj zaje..... Problem je kot sem rekel, da v podani kodi ni problema :) Lahko da se kaj skriva v ostali kodi. Poleg tega mi je pa povsem neznan in tudi nelogičen error.

Če imaš celoten program kratek ga lahko tudi celega nalimaš sem notri. Ampak res le če je zelo kratek. Ali pa poskusiš sam vse nametati v en fajl, odstraniti odvečno kodo - da prideš do nečesa podobno skrajšanega kot si tu nalimal in poskusiš prevesti.

P.S. Mislim da kompajler vrne tale error včasih, ko ne prepozna simbola napisanega izven vseh blokov. Ok, če direktno vprašam, tisti cube.vertices[0].x = -10;, kje imaš to napisano, to bolj razloži. Ker error je tak kot če bi direkt v main.cpp to dal, takoj na začetek, in ne v neko funkcijo.

Zgodovina sprememb…

  • spremenil: Gundolf ()

atasmrk ::

Ja Gundolf, tocno to je bilo. Hvala.

Zdejle se mi sele trapast zdi.

tsce4a ::

Nočem žaliti, a tvoja koda priča, da si še zelo daleč od razumevanja konceptov C++.

Če bi že moral počenjati kaj takega (uporabljati struct in #define), bi C++ programer reč spisal pribl. takole:

#define MAX_VERTEX_COUNT 2000
#define MAX_POLYGON_COUNT 2000

struct VERTEX
{
VERTEX()
: x(0), y(0), z(0)
{}

float x;
float y;
float z;
};

struct POLYGON
{
POLYGON()
: a(0), b(0),c(0)
{}

int a;
int b;
int c;
};

struct OBJECT
{
OBJECT()
: vertices(new VERTEX[MAX_VERTEX_COUNT])
, polygons(new POLYGON[MAX_POLYGON_COUNT])
{}

~OBJECT()
{
delete[] vertices;
delete[] polygons;
}

VERTEX* vertices;
POLYGON* polygons;
};

int main()
{
OBJECT cube;
cube.vertices[0].x = -10;
cube.vertices[0].y = -10;
cube.vertices[0].z = 10;

...
return 0;
}

Da ne rečem, da bi še overloadal operator reference, ki bi vrgel exception pri referiranju izven alociranega polja ter bi konstrukcije v main funkciji dal v try catch blok.

Upam da ne boš užaljen in da te bo to kvečjemu vzpodbudilo v poglabljanje v C++. Meni ni žal ... se ti odprejo programerska obzorja ... še posebej, ko se lotiš šablon (template) in še posebej ko se zgleduješ po vzorcih načrtovanja (design patterns ... recimo http://home.earthlink.net/~huston2/dp/p...

LP!

tsce4a

atasmrk ::

Ne, nisem uzaljen, se sam zavedam, da sem dalec od nekega spodobnega znanja, ampak nekje je pa reba zacet. Potem pa na takih primerih delam take banane napake.

OwcA ::

Čemu si delati težave z dinamičnim zaseganjem, če vedno zasežeš enako prostora? Pridelaš le več kode in več možnosti za napako. Če se že gremo elegantno programiranje, potem je odgovor kakšen STL kontejner.
Otroška radovednost - gonilo napredka.

atasmrk ::

No, sedaj, ko smo koncno ugotovili, kaj je bilo narobe, sem zadevo lahko malo bolj objektno naredil. Vse strukture sem spremenil v razrede, tocke in poligone pa shranil v std::vector. Se enkrat hvala.

tsce4a ::

STL conteinerji so seveda zakon. A ne nujno, če smo zelo občutljivi na hitrost in uporabljamo kakšna fiksna polja. Dinamična alokacija po moje ima skoraj vedno smisel pri večjih poljih, če le na gre za čista statična polja, ki so skupna vsem "ureničitvam" objektov istega razreda. Sicer se statična "alokacija" dogaja na skladu in ta lahko hitro preseže procesorjev obseg medpomnilnika in se program upočasni tudi pri dostopu do drugih malih "statičnih" spremenljivkah v isti funckiji, ker mora skakati ponje iz medpomnilnika. Večje bloke je zato morda vseeno bolje dinamično alocirati na heapu.

LP!

OwcA ::

Saj tudi pri STL kontejnerjih lahko v naprej poveš koliko elementov pričakuješ in se ves pomnilnik zaseže v enem koraku.
Otroška radovednost - gonilo napredka.

tsce4a ::

Kar se tiče velikosti je to res. Problem sta operatorja reference (subscript in indirection), ki sta počasnejša kot neposredno (C-jevsko) referenciranje. Res pa je, da lahko iz kontejnerja potegneš običajen C-jevski kazalec na izbrani tip in preko njega neposredno referenciraš, a to je že štrikanje in zmanjševanje berljivosti kode.

LP!
.

64202 ::

tsce4: za vektor to ne velja, vsaj na g++ in ce vklopis optimizacije:
std containers vs. own custom containers @ Slo-Tech
I am NaN, I am a free man!

OwcA ::

Za ICC takisto ne velja.
Otroška radovednost - gonilo napredka.

Gundolf ::

tsce4a, zakaj naj bi bili referenciranje počasnejše? Verjetno imaš v mislih operator[], ne? Ker kolikor jaz vem ni nič počasnejši, ker ne vključuje ničesar kar ne vključuje isti operator pri navadnih kazalcih. Drugo je če uporabljaš funkcijo at, ki ti zraven še preverja veljavnost indexa.

tsce4a ::

Hmmm... posipam se s pepelom. Priznam, da nisem vedel, da optimizatorji delajo že tako dobro. Sem preveril tri variante velikih polj doublov in res ni bilo omembe vredne razlike (le g++/cygwin varianta s STL vectorjem je bila za kakšen odstotek ali dva počasnejša ... nerelevantno)

Že pred leti so me optimizatorji "uničili", ko sem do nekega leta dosegel večje hitrosti s C-jevskim (skoraj asemblerskim ... izkušnje s signalnimi procesorji) "iteriranjem" po poljih v stilu *data++, potem pa je od nekega leta dalje postalo hitreje kar neposredno indeksiranje v stilu data[n]. Sem mislil, da se pri operatorju [] poleg copy konstrukcije izvede še "klic funkcije", torej push/pop na sklad itd.

Zdaj vidim, da sem se svoj čas po nepotrebnem mučil z lastnimi vektorji ... lahko bi jih le izpeljal iz STL vektorja in jim dodal želeno razširjeno funkcionalnost ...

Hvala za komentarje in LP!

Tr0n ::

Mogoce bi tukaj priporocal dve knjigi, ki ste nekako standard na podrocju efektivnega C++ programiranja.

Scott Meyers: Effective C++ in More Effective C++

Ravnokar sem se zacel pocasi prebijat skozi to zadevo in se lahko res neverjetno veliko naucis.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

c problem pri zaključevanju programa

Oddelek: Programiranje
61146 (971) BigWhale
»

[C#] unmanaged->managed code

Oddelek: Programiranje
112142 (2017) Zzzzzzz
»

Renderiranje filmov v realnem času?

Oddelek: Zvok in slika
121415 (1062) CaqKa
»

Collision detection

Oddelek: Programiranje
81925 (1677) Senitel

Več podobnih tem