abonnement Unibet Coolblue Bitvavo
  vrijdag 28 januari 2011 @ 15:11:18 #1
189216 netolk
maar dan andersom
pi_91990814

Nu mét gratis web-support!

Als je vragen hebt over C of C++, dan zit je hier goed met een (hopelijk later grote) kliek guru's.
Beperk je vragen niet tot "hij doet het niet" of "hij geeft een fout" - onze glazen bol is kapot en we willen graag van je weten wát er niet lukt en wélke foutmelding je precies krijgt. ;)

En onthoud: lieve modjes maken dit topic centraal! O+

Vorige delen:
[C(++)] voor dummies - Deel 1
[C(++)] voor dummies - Deel 2

:? FAQ :?

:? Ik wil beginnen met C/C++, wat voor IDE is het beste voor mij?
Dat ligt eraan. Als je alléén voor MS Windows wilt gaan developen, is Visual Studio de beste optie. Deze kun je bovendien als je student bent via Microsoft DreamSpark of MSDN Academic Alliance gratis downloaden. :)
Wil je echter cross-platform (dat wil zeggen: voor b.v. Windows én Linux, of Linux én Mac) gaan developen, dan zijn Dev-C++ en Code::Blocks de beste optie voor C++. Eclipse (ook voor C) en NetBeans zijn ook goede keuzes, alleen zijn deze meer op Java gericht. Een ander IDE, van Nokia's hand, is Qt Creator. Dit IDE maakt gebruik van het Qt-framework, een set van functies, types, variabelen etc. om programmeren makkelijker te maken. Dit framework is cross-platform. :)

:? Hoe gebruik ik x/wat houdt y in?
Stop! Voor vragen hoe je bepaalde ingebouwde functies, types of classes gebruikt kun je de C referentie of de C++ referentie gebruiken. Hier staat alles in wat je nodig hebt. :)

:? Wat is het verschil tussen C en C++?
C++ is, eenvoudig gezegd, een nieuwere versie van C (vandaar ook de naam, C++ wil zeggen: verhoog de waarde van C met 1). Het biedt onder andere betere klasse-ondersteuning en verschillende nieuwe types, zoals vectors en maps, om er maar een paar te noemen.
Als je wilt beginnen met leren, is C++ beter, want C wordt eigenlijk niet vaak meer gebruikt.

:? Wat is het Windows SDK?
Het Windows SDK is een set van functies, gemaakt door Microsoft, om het programmeren voor Windows te vereenvoudigen.
Als je ervoor kiest het Windows SDK te gebruiken, houd er dan rekening mee dat je applicatie Windows-only wordt!
Je kunt de laatste versie hier vinden ter download. :)

Handige links:

Referenties en tutorials:
Leer C en/of C++ (engels)
Leer programmeren met het Windows SDK (engels)
Info over het Windows SDK (engels)

Deze OP vind je hier.
Beware of the Raping Zebra's
  vrijdag 28 januari 2011 @ 15:32:36 #2
254493 Trollface.
gr rob fruithof, groningencity
pi_91991775
1
2
3
4
5
6
#include <cstdio>

int main() {
    printf("%c%c%c\n", 'T', 'V', 'P');
    return 0;
}
★5731U★ Death from above '79★You're a woman, i'm a machinielsie ★ ✠ ★ Telkens weer een beetje sterven★ I was born in a winterstorm, i live there still★
pi_91993326
Tvp* tvp = new Tvp();
  vrijdag 28 januari 2011 @ 18:10:44 #4
189216 netolk
maar dan andersom
pi_91999263
zou iemand kunnen uitleggen waarom het volgende niet werkt?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>
class Master{
    protected:
        unsigned short i;
    public:
        Master():i(5){}
        virtual unsigned short get(){return 9;}
};
class Sub:public Master{
    public:
        Sub(){i=8;}
        unsigned short get(){return i;}
};

int main(){
    Master *M_ptr;
    
    Sub mySub;
    
    M_ptr = &mySub;
    
    Sub *S_ptr = dynamic_cast<Sub*>(M_ptr);
    if(S_ptr) // hier werkt het
        std::cout << "Works\n";
    else
        std::cerr << "FAIL\n";
    
    std::vector<Master> myVec;
    myVec.push_back(Sub());
    Master *vec_ptr = &myVec[0];
    Sub *S_ptr2 = dynamic_cast<Sub*>(vec_ptr);
    if(S_ptr2) // hier faalt het
        std::cout << "Works\n";
    else
        std::cout << "FAIL\n";
    
    return 0;
}

waarom werkt dynamic_cast niet als er een pointer naar een vecor wijst?
Beware of the Raping Zebra's
pi_92005650
Een van de problemen is dat een object van base class niet per se dezelfde geheugenruimte inneemt als een object van een derived class. Een dynamic cast werkt in principe alleen met pointers en references. Je definieert een vector van Masters, daar kun je niet zo een twee drie een Sub in stoppen want daar wordt dan gebruik gemaakt van slicing ipv polymorfisme: de Sub is niet echt een Sub maar wordt geconverteerd naar een Master. Met een vector<Master*> of een vector<Master&> gok ik dat je meer succes hebt.

Moraal van het verhaal: value-typed class objecten zijn gewoon zwaar kut. Een van de vele designfoutenblunders in C++ om zoiets toe te laten.
pi_92020859
Nog een probleem met je code is dat je de base class niet polymorf hebt gemaakt. Er moet tenminste 1 virtual methode in zitten; het is sowieso raadzaam om de destructor virtual te maken. Dat classes niet automatisch polymorf zijn is overigens ook een designflater.
  zaterdag 29 januari 2011 @ 12:18:41 #7
189216 netolk
maar dan andersom
pi_92034038
quote:
1s.gif Op zaterdag 29 januari 2011 00:15 schreef thabit het volgende:
Nog een probleem met je code is dat je de base class niet polymorf hebt gemaakt. Er moet tenminste 1 virtual methode in zitten; het is sowieso raadzaam om de destructor virtual te maken. Dat classes niet automatisch polymorf zijn is overigens ook een designflater.
um, die destructor klopt idd maar er is toch een virtual methode?

virtual unsigned short get(){return 9;}
Beware of the Raping Zebra's
pi_92034278
quote:
1s.gif Op zaterdag 29 januari 2011 12:18 schreef netolk het volgende:

[..]

um, die destructor klopt idd maar er is toch een virtual methode?

virtual unsigned short get(){return 9;}
O ja, overheen gelezen. Maar dan nog moet je geen polymorfisme toepassen op value-typed objecten.
  zaterdag 29 januari 2011 @ 17:41:29 #9
189216 netolk
maar dan andersom
pi_92046703
hmm... ik krijg behoorlijk wat compilatie fouten bij het declareren van std::vector<Master&> iets van
1mingw/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/ext/new_allocator.h:52: error: forming pointer to reference type `Master&'

en nog veel meer...

maar std::vector<Master*> werkt wel :)
Beware of the Raping Zebra's
pi_92047159
Pas wel een beetje op dat je geen pointers naar ongedefinieerde stukken geheugen laat wijzen.
  zaterdag 29 januari 2011 @ 18:01:56 #11
189216 netolk
maar dan andersom
pi_92047496
quote:
1s.gif Op zaterdag 29 januari 2011 17:52 schreef thabit het volgende:
Pas wel een beetje op dat je geen pointers naar ongedefinieerde stukken geheugen laat wijzen.
Ja, ik heb het zo bedacht:
[code]
Master *M_ptr = new Sub();
myVec.push_back(M_ptr);

en dan de destructor v.e class waar Master in zit:
~Class{
for(int i = 0; i < myVec.size(); i++){
delete myVec[i];
}
myVec.clear();
}

nog een vraagje, roept een vector bij destruction ook de destructor van het type aan? dus zegmaar std::vector<int> roept die dan ook ~int() aan?
Beware of the Raping Zebra's
pi_92048298
De destructor van de vector roept de destructors van de objecten aan die ruimte innemen in het stuk heap dat de vector zelf gealloceerd heeft. Dus niet als het pointers zijn. Dingen die je zelf met new aanmaakt moet je ook zelf deleten.

Een int heeft trouwens niet echt een destructor je kunt (denk ik) wel ~int() aanroepen, maar dat is puur om de syntax consistent de houden, de instructie doet helemaal niets.
pi_92050027
quote:
1s.gif Op zaterdag 29 januari 2011 18:01 schreef netolk het volgende:

nog een vraagje, roept een vector bij destruction ook de destructor van het type aan? dus zegmaar std::vector<int> roept die dan ook ~int() aan?
Ja, als er een destructor bestaat zal deze aangeroepen worden. Dit geldt echter alleen als je classes (of base-types) in de vector opslaat. Als je std::vector<X*> gebruikt, zal de X::~X() destructor niet automatisch aangeroepen worden. Daarom wordt het ook als niet netjes gezien om pointers in containers op te slaan.

Edit: Oh, ik had het bovenstaande antwoord gemist.
"Slechts diegene mag slopen die iets beters kan bouwen."
pi_92050256
Niks mis met pointers in containers, mits je duidelijk aan elke new een delete koppelt.
pi_92050496
quote:
1s.gif Op zaterdag 29 januari 2011 19:19 schreef thabit het volgende:
Niks mis met pointers in containers, mits je duidelijk aan elke new een delete koppelt.
Gaat tegen het idee van de stl containers in, namelijk dat de container de eigenaar van de data is. Netter zou zijn de pointer in een class te wikkelen. Dit is echter erg afhankelijk van smaak en stijl, en iedereen weet dat daarover prima te twisten valt. :)
"Slechts diegene mag slopen die iets beters kan bouwen."
pi_92050860
Als je dat soort design patterns al moet gaan toepassen, dan kun je beter op een programmeertaal overstappen waar ze helemaal niet nodig zijn. :).
pi_92051592
1
2
long long troll[2]={7308604865845225588LL, 0};
printf("%s\n", (char *)troll);

*O*
  zaterdag 29 januari 2011 @ 20:38:45 #18
85514 ralfie
!Yvan eht nioj
pi_92053330
quote:
1s.gif Op zaterdag 29 januari 2011 19:25 schreef GS42 het volgende:

[..]

Gaat tegen het idee van de stl containers in, namelijk dat de container de eigenaar van de data is. Netter zou zijn de pointer in een class te wikkelen. Dit is echter erg afhankelijk van smaak en stijl, en iedereen weet dat daarover prima te twisten valt. :)
Mensen kiezen vaak voor c++ vanwege de snelheid, niet omdat de taal zo lekker netjes weg te tikken is... Daarvoor zijn veel geschiktere talen (met garbage collector etc)
  zaterdag 29 januari 2011 @ 21:05:17 #19
189216 netolk
maar dan andersom
pi_92054468
die ~int() was even een dummie voor de vraag, maar ik heb dus zo'n vector<Player> waar maar 1 player instaat en toch word de destructor 2x aangeroepen...
quote:
1s.gif Op zaterdag 29 januari 2011 19:14 schreef GS42 het volgende:

[..]

Ja, als er een destructor bestaat zal deze aangeroepen worden. Dit geldt echter alleen als je classes (of base-types) in de vector opslaat. Als je std::vector<X*> gebruikt, zal de X::~X() destructor niet automatisch aangeroepen worden. Daarom wordt het ook als niet netjes gezien om pointers in containers op te slaan.

Edit: Oh, ik had het bovenstaande antwoord gemist.
tja ik kan het ook in een matrix / array zetten maar dat is weer gekut als je er data aan toe wilt voegen, dan kan dat wel met classes die dan naar het volgende object wijzen maar waarom zou ik dat doen als ik ook gewoon vector<int*> kan gebruiken? en het dan via een destructor kan laten verwijderen
Beware of the Raping Zebra's
  zaterdag 29 januari 2011 @ 21:10:57 #20
189216 netolk
maar dan andersom
pi_92054675
code bij mijn vorige post

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
class Temp{
    int i;
    public:
        Temp(){}
        ~Temp(){
            std::cout << "Destructor\n";
        }
};
int main(){
    std::vector<Temp> myvec;
    myvec.push_back(Temp());
    
    return 0;
}
output:
1
2
Destructor
Destructor

en als ik de push_back(Temp()) weglaat roept ie de destructor helemaal niet aan, maar waarom word de destructor 2x aangeroepen als er maar 1 object is?
Beware of the Raping Zebra's
pi_92054691


[ Bericht 100% gewijzigd door thabit op 29-01-2011 21:11:28 (was te snel) ]
  zaterdag 29 januari 2011 @ 21:11:40 #22
189216 netolk
maar dan andersom
pi_92054709
quote:
1s.gif Op zaterdag 29 januari 2011 21:11 schreef thabit het volgende:

:P

of ik te laat
Beware of the Raping Zebra's
pi_92054815
quote:
1s.gif Op zaterdag 29 januari 2011 21:05 schreef netolk het volgende:
die ~int() was even een dummie voor de vraag, maar ik heb dus zo'n vector<Player> waar maar 1 player instaat en toch word de destructor 2x aangeroepen...
Dat is mogelijk en niets om je zorgen over te maken. Bij het kopieren naar de vector is het mogelijk dat er een kopie gemaakt moet worden en dus voor het oude object een destructor aangeroepen wordt. (Sterker nog, aan de code van je kun je zien dat de compiler dit moet doen.) Ook moet een vector zichzelf vaak in geheugen verplaatsen waarbij het kopieen van objecten moet maken en de destructor kan gebruiken, evenals de copy constructor van de klasse (maar dit zou bij 1 object niet moeten gebeuren).

quote:
tja ik kan het ook in een matrix / array zetten maar dat is weer gekut als je er data aan toe wilt voegen, dan kan dat wel met classes die dan naar het volgende object wijzen maar waarom zou ik dat doen als ik ook gewoon vector<int*> kan gebruiken? en het dan via een destructor kan laten verwijderen
Bijvoorbeeld in het vorige voorbeeld. Als je de pointer in een klasse wikkelt die de geheugenafhandeling doet, hoef je er op dit moment niet meer aan te denken. Anders moet je voor elke klasse die een vector<int*> gebruikt, een destructor, copy constructor en eventueel een operator=() schrijven, terwijl een vector<IntPointer> dit zelf op zou kunnen lossen. Maar opnieuw: dit heeft veel met persoonlijke stijl te maken.
"Slechts diegene mag slopen die iets beters kan bouwen."
pi_92054972
quote:
1s.gif Op zaterdag 29 januari 2011 21:10 schreef netolk het volgende:
code bij mijn vorige post

[ code verwijderd ]

output:

[ code verwijderd ]

en als ik de push_back(Temp()) weglaat roept ie de destructor helemaal niet aan, maar waarom word de destructor 2x aangeroepen als er maar 1 object is?
Omdat er 2 Temp-objecten zijn. ;). Zie je waarom?
  zaterdag 29 januari 2011 @ 21:19:14 #25
189216 netolk
maar dan andersom
pi_92055025
quote:
1s.gif Op zaterdag 29 januari 2011 21:17 schreef thabit het volgende:

[..]

Omdat er 2 Temp-objecten zijn. ;). Zie je waarom?
JA, ik zie het nu :) tenminste, omdat ie een copy maakt van de Temp() die ik declareer in de push_back() toch?
Beware of the Raping Zebra's
abonnement Unibet Coolblue Bitvavo
Forum Opties
Forumhop:
Hop naar:
(afkorting, bv 'KLB')