|
This thread is locked; no one can reply to it. |
1
2
|
A few C++ basics |
james_lohr
Member #1,947
February 2002
|
I thought I'd start using C++ for the first time mainly because I wanted Java-style multi-threading (Boost's C++ thread library is great!). Anyway, I've not got the time to read up on C++ (exams approaching), so I thought I'd just jump straight in and deal with the problems as they occur. First question: Is the following a memory leak? MyObject newObj; //ie what does this line do exactly? newObj = MyObject(arg1,arg2); Is this prefered? : MyObject *newObj; newObj = new MyObject(arg1,arg2);
|
Kitty Cat
Member #2,815
October 2002
|
Quote:
Is the following a memory leak? Not necessarilly. It allocates an object on the stack, and runs it's default contructor (first line), then it allocates another object and copies it over the original. as long as the object itself takes care not to leak memory, there's no problem. I'd say the latter is preferred, though. You generally don't allocate objects on the stack unless they're small with specific uses. -- |
james_lohr
Member #1,947
February 2002
|
Quote: Not necessarilly. It allocates an object on the stack, and runs it's default contructor (first line), then it allocates another object and copies it over the original. as long as the object itself takes care not to leak memory, there's no problem. I see, so MyObject(arg1,arg2) also creates an object on the stack which is discarded after the copy? Can't I declare an object without creating anything (without using the pointer approach) ?
|
Kitty Cat
Member #2,815
October 2002
|
Quote: Can't I declare an object without creating anything (without using the pointer approach) ?
extern -- |
james_lohr
Member #1,947
February 2002
|
Ok great. So even if there is no zero-parameter constructor specified in the class, MyObject myobj; will still construct an object regardless - as if a MyObject(){} was present in the class?
|
BAF
Member #2,981
December 2002
|
Can you make the default constructor with 0-parameters private to disallow "MyObject myobj;" ? |
CGamesPlay
Member #2,559
July 2002
|
You can. -- Ryan Patterson - <http://cgamesplay.com/> |
james_lohr
Member #1,947
February 2002
|
Ok, so if objects exist on the stack, then (unlike Java) the following won't work? MyObject *a; { MyObject newObj(1,2,3); a = &newObj; } a->doSomething();
|
CGamesPlay
Member #2,559
July 2002
|
That will crash, yes. -- Ryan Patterson - <http://cgamesplay.com/> |
gillius
Member #119
April 2000
|
That might work fine if doSomething was inlined so that the stack is not corrupted... But you have a dangling pointer here so the behavior is undefined even if it doesn't crash. For basic stuff, C++ isn't magical. You've probably done the same in C and Allegro is object-oriented as well. In C, defining a struct and then declaring a struct object actually builds it (and this is identical in C++ when using default constructor). The following C++ and C code are equivalent in the generated binary code (ignoring a pedantic detail): MyObject a(1, 2, 3); a.doSomething(); //C code MyObject a; create_a( &a, 1, 2, 3 ); doSomething( &a ); Basically basic object stuff in C++ you can just basically assume it's like a C function with a hidden "this" parameter. There's a little more to it than that, which would rile up a lot of C++ experts here, but that's basically it. Gillius |
james_lohr
Member #1,947
February 2002
|
Someone mind explaining defaults? - this snippet is taken from the OpenLayer demo: Particle( float x, float y, ColorScheme scheme, float minSpeed = particleSpeedMin, float maxSpeed = particleSpeedMax, float startAngle = particleStartAngle, float angleSpread = particleMaxAngleSpread, float gravity = particleGravity ) : gravity( gravity ), circle( Vec2D( x, y ), 1.0 ) { . . . } It is a constructor. What exactly does the stuff following ":" mean? Also, what is the signature for this function if I want to make a header file?
|
Trezker
Member #1,739
December 2001
|
That's initializing. |
james_lohr
Member #1,947
February 2002
|
Thanks. Another topic completely: what's the deal with enums and header files? - Do I need to make a global header with all enums?
|
CGamesPlay
Member #2,559
July 2002
|
Quote: Do I need to make a global header with all enums? Not at all. You can put enums wherever you can put classes. -- Ryan Patterson - <http://cgamesplay.com/> |
Trezker
Member #1,739
December 2001
|
Never ever make a global header, if you have a global header you've done something wrong. |
CGamesPlay
Member #2,559
July 2002
|
Quote: Only include the least amount of headers neccesary to compile. So you mean like one global header? -- Ryan Patterson - <http://cgamesplay.com/> |
Kitty Cat
Member #2,815
October 2002
|
Quote: What exactly does the stuff following ":" mean? It's an initialization list and it allows you to initalize the members of the class. Basic types like int or char* can take something of equal type and will be set to it. But for something like a class it allows you to use a non-default contructor. Like so: class Foo { Foo(int a); } class Bar { Foo foo; Bar(int a) : foo(a) { /* foo will have initialized using the non-default constructor */ } }; Note that compilers will complain if you initialize class members out of order. -- |
james_lohr
Member #1,947
February 2002
|
Ok, next thing: circular dependencies. Seems pretty fundamental, I'm not sure why I've never encountered this problem in plain C, but anyway: Suppose class A uses class B, class B uses C and C uses A. file A.hpp: #include "B.hpp"
...
file B.hpp: #include "C.hpp"
...
file C.hpp: #include "A.hpp"
...
How do you usually solve this issue? - If I try to use forward declarations, I get "invalid use of undefined type".
|
CGamesPlay
Member #2,559
July 2002
|
Don't use the type. You need to forward declare the types, and you need to put the method bodies inside the source files. -- Ryan Patterson - <http://cgamesplay.com/> |
james_lohr
Member #1,947
February 2002
|
Quote: Don't use the type. What exactly do you mean?
|
Kitty Cat
Member #2,815
October 2002
|
// a.hpp: class B; class A { B *foo; void somefunc(); }; // a.cpp: void A::somefunc() { foo->blah(); }
-- |
james_lohr
Member #1,947
February 2002
|
That doesn't work. As I said, it gives an "invalid use of undefined type" at foo->blah();
|
CGamesPlay
Member #2,559
July 2002
|
You forgot to #include b.h in a.cpp. -- Ryan Patterson - <http://cgamesplay.com/> |
james_lohr
Member #1,947
February 2002
|
That's what I was doing originally, but it gave some bizzare linker errors. Tried it again, got the linker errors again.. but after a second rebuild of everything they went away. So it's working now at least. Thanks
|
ImLeftFooted
Member #3,935
October 2003
|
Quote: It is a constructor. What exactly does the stuff following ":" mean? After : is a comma delimited list of constructor calls for all inherited classes and attributes. Its also valid C++ to put in try and catch blocks. Quote: Also, what is the signature for this function if I want to make a header file? Well this function probably already exists in a header, as default parameters can only be specified in a function definition (this is Java style). If you were to separate the function into a header definition and implement the function elsewhere in some cpp file the function would probably look like this: Particle( float x, float y, ColorScheme scheme, float minSpeed = particleSpeedMin, float maxSpeed = particleSpeedMax, float startAngle = particleStartAngle, float angleSpread = particleMaxAngleSpread, float gravity = particleGravity ); Note that the : syntax is only valid in the actual function implementation (ie in the .cpp file). Also note the semicolon. |
|
1
2
|