calling destructor versus new object

Started by
45 comments, last by Sigvatr 10 years, 7 months ago

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?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

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.

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.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Assign a temporary "clean" object to the one you want to reset if possible.

scene = Scene();

o3o

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.

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

Stephen M. Webb
Professional Free Software Developer

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


- 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.

Previously "Krohm"

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.

Stephen M. Webb
Professional Free Software Developer

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...

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement