Jump to content
  • Advertisement
Sign in to follow this  
cozzie

calling destructor versus new object

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

Just wondering, when I run my d3d engine main program, I have 1 instance of the class d3dscene.

When I go to another scene, I call the destructor and load the new one.

This keeps my main loop clean, always rendering the same d3dscene object.

 

My question;

- what would be 'better', create a regular 'object' on the stack, i.e. "engine::d3dscene myscene", when finished manually call the destructor + constructor and then call it's member function 'loadscene'?

 

versus

 

- engine::d3dscene *myscene = new engine::d3dscene;

and when finished, delete myscene and again "*myscene = new engine::d3dscene

 

In the 1st option calling the constructor is necessary to reset all counters, vars etc., and it's working fine.

 

What would you say?

Edited by cozzie

Share this post


Link to post
Share on other sites
Advertisement
I would make an instance part of my scene object, and then the constructors and destructors will get called at the right times without doing anything special.

EDIT: Oh, but then you might have the same question about your scene object, so I probably didn't really answer the question. If scenes can be assigned, you might be able to do the clean-looking thing using assignment of objects. Edited by Álvaro

Share this post


Link to post
Share on other sites

Hi alvaro.

Thanks, not sure if I understand it though.

 

I'm talking about the main objects of my application (containing mesh instances, audio, etc.).

So basically:

Engine_d3drenderer::	CD3d		_d3d;
Engine_d3drenderer::	CD3dcam		_d3dcam(D3DXVECTOR3(0.0f, 0.0f, 0.0f)); 
Engine_d3drenderer::	CD3dscene	_d3dscene;

Engine_dxinput::		CDinput		_dinput; 
Engine_audio::			CAudio		_audio;

Engine_IO::				CScene		_scene;
Engine_general::		CTimer		_timer;
Engine_game::			CPlayer		_player(Crealysm_math::VECTOR3(0.0f, 0.0f, 0.0f));

Where _scene, _d3dscene and _audio will be 'renewed' when I load another scene.

What I do know is:

// destruct the IO Scene, D3D scene and camera object
_scene.~CScene();
_d3dscene.~CD3dscene();
_d3dcam.~CD3dcam();

And then just call the member functions for loading the new scene etc.

 

My question is if it would be better do make a pointer to the object for those 3 'varying' objects:

Engine_d3drenderer::	CD3dcam		*_d3dcam = new Engine_IO::d3drenderer::CD3dcam(D3DXVECTOR3(0.0f, 0.0f, 0.0f)); 
Engine_d3drenderer::	CD3dscene	*_d3dscene = new Engine_IO::d3drenderer::CD3dscene;
Engine_IO::		CScene		*_scene = new Engine_IO::CScene;

And then when loading a new scene:

_scene = new Engine_IO::CScene;
_d3dscene = new Engine_d3drenderer::CD3dscene;
_d3dcam = new Engine_d3drenderer::CD3dcam;

Where to 2nd option prevents me from calling both the destructor and constructor manually I think.

This would also prevent me from throwing around the whole object in functions, instead of just a a pointer.

Share this post


Link to post
Share on other sites

I find the manual destructor calling highly suspicious. It's an obscure c++ feature that you should only use if you know 100% what you are doing and isn't needed for regular day to day programming at all. Why don't you delete your objects and then new them?

 

Edit:

 

I should try to read better. The first part still stands though.

Waterlimon's suggestion is good. Alternatively reset all the variables in the loadscene method. After all, you could call the loadscene method more than once, so it should leave the scene in a clean state.

Edited by Madhed

Share this post


Link to post
Share on other sites

Hey, you can't call a constructor.  You can construct an object (in which case the constructor gets invoked), but the C++ language provides no way to call a constructor directly.

 

If you're doing what I think you're doing, you're probably invoking the destructor directly (which is, technically, undefined behaviour for objects not created using placement new) and then calling an initializer function to reset the object values.  The proper way to do that in C++ is to use the assignment operator to assign a new object value to the existing object instance.

 

For example:

Engine_d3drenderer::CD3dscene    _d3dscene;
// ... use the scene
_d3dscene = Engine_d3drenderer::CD3dscene(); // destroy the old object and assign a new, freshly initialized value

Share this post


Link to post
Share on other sites

Placement new is effectively a direct call to the constructor. You can also call it directly like any other member function. See http://www.gamedev.net/page/resources/_/technical/general-programming/wade-not-in-unknown-waters-part-one-r3290 for examples.

 

My suggestion would be to use new and delete as normal. In general when in doubt, you should probably go for whatever solution will be simplest to understand. Being easy to understand means it should also be easier to debug and change later if you need to do so.

 

 

 

Edit: You can't actually call the constructor directly like a normal function. I still say placement new does the same thing as calling the constructor would, even for non-POD classes. That's what it's there for. http://www.drdobbs.com/cpp/calling-constructors-with-placement-new/232901023?pgno=2

Edited by Adam_42

Share this post


Link to post
Share on other sites


- what would be 'better', create a regular 'object' on the stack, i.e. "engine::d3dscene myscene", when finished manually call the destructor + constructor and then call it's member function 'loadscene'?
Better according to what? Sure not about perf: with 1 creation every... couple of minutes?

Anyway, when putting stuff on stack, don't force your rules. Just let normal scope rules take care of that. Put it inside a loop, a brace block an if, what fits your liking.

FYI, my current scene manager is manually managed through new/delete, being part of a much higher-level, longer-living object. Never even spotted it on the profiler.

Architecturally speaking, I'd prefer to avoid using new/delete whatever possible but for this specific example I think there's just too little to gain.

Share this post


Link to post
Share on other sites

Placement new is effectively a direct call to the constructor. You can also call it directly like any other member function.

No it's not and no you can't.

When an object is constructed, even using placement new, more than just the constructor body is invoked. Yes, if you have a simple class without any kind of inheritance in which all its members are PODs and there is no initializer list, and you aren't using exceptions or RTTI anywhere in your application, placement new is effectively the same as calling the constructor like a function but using a weird syntax. That's a pretty broad range of restrictions to say placement new is effectively a direct call to the constructor. It's more accurate to say "constructing and object using placement new is a way of constructing an object, and one of the things that happens when an object is constructed is that the constructor is invoked."

A conformant compiler will not allow a constructor to be invoked directly since it does not have a name and does not participate in name lookup (see [12.1](2) of the standard) -- it should result in a compile-time error.

Share this post


Link to post
Share on other sites

Thanks all.

I'm now trying to initialize the scene as a fresh object, like Bregma suggested and showed in his example.

 

Unfortunately no luck yet, because that line "CScene = engine::IO:CScene()" is giving an access violation error.

Maybe somewhere in my message handling/ que some handling goes on in the background and that's why I get the error.

 

Update;

I also get the access violation when I try to set the CScene with this code in the beginning of the application, when nothing is done yet with the object.

So strange, since it all works fine with my camera class/ object...

Edited by cozzie

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!