Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » A few C++ basics

This thread is locked; no one can reply to it. rss feed Print
 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
avatar

Quote:

Is the following a memory leak?

MyObject newObj; //ie what does this line do exactly?
newObj = MyObject(arg1,arg2);

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.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

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
avatar

Quote:

Can't I declare an object without creating anything (without using the pointer approach) ?

extern
If you're meaning you want to use the non-default constructor right off the bat, you can do this:
MyObject myobj(arg1, arg2);

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

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
avatar

Can you make the default constructor with 0-parameters private to disallow "MyObject myobj;" ?

CGamesPlay
Member #2,559
July 2002
avatar

You can.

--
Tomasu: Every time you read this: hugging!

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
avatar

That will crash, yes.

--
Tomasu: Every time you read this: hugging!

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
Gillius's Programming -- https://gillius.org/

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
avatar

That's initializing.
Instead of doing member=value in the function body you do it like that.
This is supposedly faster, but I don't know the specifics.

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
avatar

Quote:

Do I need to make a global header with all enums?

Not at all. You can put enums wherever you can put classes.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Trezker
Member #1,739
December 2001
avatar

Never ever make a global header, if you have a global header you've done something wrong.
Only include the least amount of headers neccesary to compile.

CGamesPlay
Member #2,559
July 2002
avatar

Quote:

Only include the least amount of headers neccesary to compile.

So you mean like one global header? :P

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Kitty Cat
Member #2,815
October 2002
avatar

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.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

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
avatar

Don't use the type. You need to forward declare the types, and you need to put the method bodies inside the source files.

--
Tomasu: Every time you read this: hugging!

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
avatar

// a.hpp:
class B;

class A {
   B *foo;
   void somefunc();
};

// a.cpp:
void A::somefunc()
{
   foo->blah();
}

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

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
avatar

You forgot to #include b.h in a.cpp.

--
Tomasu: Every time you read this: hugging!

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
avatar

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 


Go to: