Public Group

This topic is 1029 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

When creating an object in C++ I would like to create the object and call a function inside that object at the same time. For instance, say I have a "Level" class and inside that class there is a function that loads the level called "load(string level)".

Level level;
level.load("level1");

Is there any way to do something like this:

Level level = new Level("level1").load; // I believe this is possible in Java, however it has been quite a while since I programmed in Java.

And I know that the "new" keyword functions a lot different in C++ than it does in Java, so I have been reluctant to try anything that included using it. It is not that big of an issue I just think it looks nicer when it's all on one line.

Edited by Dark Sage

##### Share on other sites

Level level("level1");


##### Share on other sites

That makes sense. Guess it's just because I haven't learned about destructors yet, and I would assume that if I am doing the level loading in the constructor I would have to destruct the old level before loading another one. I could just be over complicating it though...

##### Share on other sites

Hello, you're mixing up a couple of things.

Firstly, you want to do stuff on the same line. This is easier than you think:

Level level; level.Load("level1");


Tadaa! However, in general, it is more readable to use shorter lines, especially since debuggers usually work on a per line basis. So, stepping through the line above will likely be quite awkward.

Secondly, you're talking about new, constructors and destructors.

Let me try to untangle this a bit.

Whether you use "new" or not, an objects constructor and destructor will still be run (if it has any). So they don't have anything to do with the use of "new".

Instead, "new" will change where the object will life and therefore influence it's lifetime.

In short, without "new", the object will live until the current scope ends (at the next "}"). With "new", the object will live until "delete" is called on it.

For a more detailed explanation, this looks to be fairly comprehensive:

http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/

For the sake of completeness, here's how the above example would work with "new", again as a single line.:

Level* level = new Level(); level->load("level1");


I hope that helps!

##### Share on other sites

Oh, another thing: In Java, objects are *always* on the heap, so you don't have a choice to make there. Only primitives (int, float,...) are on the stack.

##### Share on other sites

Hello, you're mixing up a couple of things.

Firstly, you want to do stuff on the same line. This is easier than you think:

Level level; level.Load("level1");


Tadaa! However, in general, it is more readable to use shorter lines, especially since debuggers usually work on a per line basis. So, stepping through the line above will likely be quite awkward.

Secondly, you're talking about new, constructors and destructors.

Let me try to untangle this a bit.

Whether you use "new" or not, an objects constructor and destructor will still be run (if it has any). So they don't have anything to do with the use of "new".

Instead, "new" will change where the object will life and therefore influence it's lifetime.

In short, without "new", the object will live until the current scope ends (at the next "}"). With "new", the object will live until "delete" is called on it.

For a more detailed explanation, this looks to be fairly comprehensive:

http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/

For the sake of completeness, here's how the above example would work with "new", again as a single line.:

Level* level = new Level(); level->load("level1");


I hope that helps!

Thanks for your help and information. Clears up a few things I was definitely confused about haha.

##### Share on other sites

A final note FYI.

Do not call overriden functions (pure virtual) from base class ctor. So you cannot do something like:

class Asset {
public:
Asset(const std::string &foo) { Load(foo); }
protected:
virtual void Load(const std::string &foo) = 0;
};

class Level : public Asset {
public:
Level (const std::string &foo) : Asset(foo) { }
protected:
// Pull physics
// Pull textures
// Pull sound resources
}
};


To build a Level object the runtime first builds the Asset object. When the Asset object ctor is run, it has no information about what's really running and you'll be screwed big way. I think some compilers warn you or even prevent you from doing that. I am 100% sure I have been screwed in the past.

If memory serves, Java allows this for some reasons I don't remember. I'd suggest to be careful with that.

EDIT: see Brother Bob for a more "technically correct" explanation. I still suggest to stay away from those things but that's opinion at this point.

Edited by Krohm

##### Share on other sites

Level (const std::string &foo) : Asset(foo) { }

Careful with that.

How long does loading a level take?  A half second?  Five seconds? Ten seconds? Two minutes?

Temporary objects get created all the time.  Sometimes you want to create empty objects, such as when you allocate an array of things.

It is generally best to provide a default constructor that does nothing except create an empty object, and a copy constructor that generally works with shallow copies of members. In this case the default constructor would be an unloaded level. This should only initialize the values needed to specify the level is unloaded, and return immediately.

You can still write constructors with parameters like that, internally they call the load function and wait for the seconds or minutes required to do the job.  But make sure those are not the ONLY constructor you create.  Build an instantly constructable default as well.

##### Share on other sites

A final note FYI.

Do not call overriden functions (virtual) from base class ctor. So you cannot do something like:

class Asset {
public:
Asset(const std::string &foo) { Load(foo); }
protected:
virtual void Load(const std::string &foo) = 0;
};

class Level : public Asset {
public:
Level (const std::string &foo) : Asset(foo) { }
protected:
// Pull physics
// Pull textures
// Pull sound resources
}
};


To build a Level object the runtime first builds the Asset object. When the Asset object ctor is run, it has no information about what's really running and you'll be screwed big way. I think some compilers warn you or even prevent you from doing that. I am 100% sure I have been screwed in the past.

If memory serves, Java allows this for some reasons I don't remember. I'd suggest to be careful with that.

Java and C# allow this because the construction of a derived object runs in the opposite fashion from a C++ object. In Java/C# first the derived object is created with its associated vtable, this means that the constructor knows where to dispatch a virtual function call too. In C++ first the base object is created and then the derived version, calling a virtual function is in that case undefined behaviour for C++.

##### Share on other sites

In C++ first the base object is created and then the derived version, calling a virtual function is in that case undefined behaviour for C++.

Calling virtual functions form the base class constructor is perfectly fine and well specified. During construction of the Asset base class, the concrete type of the object is Asset (the concrete type is not Level until later during construction) and the virtual call is dispatched to Asset::Load.

Since Asset::Load is pure there is a chance it also has no implementation. In that case I believe the behaviour of calling Load is undefined. Otherwise, there are no problems calling virtual functions other than ones understanding of the rules.

1. 1
Rutin
24
2. 2
3. 3
JoeJ
18
4. 4
5. 5

• 38
• 23
• 13
• 13
• 17
• ### Forum Statistics

• Total Topics
631706
• Total Posts
3001835
×