Pointer to a const reference?

Started by
9 comments, last by cozzie 10 years, 7 months ago
Hi,

I currently have around 10 member functions in my scenegraph class, needing a const reference to my d3dscene object. For example (pseudo code):

Class scenegraph
{
bool CullLights(const d3drenderer::cd3dscene &pd3dscene);
....
....
}

When in this sort of situation I would need a pointer to i.e. another object, I create a member variable to save the pointer in the class object. Example:

Class scenegraph
{
d3drenderer::d3dscene *mD3dscene;

bool CullLights();
.....
.....
}

This way in can reuse the pointer in all the member functions, without passing the pointer over and over again in each member function call.

My question is, can I do the same with a const reference instead of a pointer?
The reason is that I don't want the scenegraph to make changes to the d3dscene, just 'read/access only'.

Could I do something like this?

Class scenegraph
{
d3drenderer::d3dscene *&mD3dscene;

void Setup(const d3drenderer::d3dscene &pScene);
....
....
}

void SceneGraph::Setup(const d3drenderer::d3dscene &pScene)
{
mD3dscene = pScene;
....
....
}

I think this should work, but not sure about pointing to the address versus pointing to the object which the address is pointing too.

Can someone help me out?

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

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

Advertisement

I think a pointer to a reference is illegal.

Just pass *mD3dscene to functions which take const d3drenderer::d3dscene& as arguments.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
Hi.
If i understand you correct, then that's what I'm trying to avoid.

I wonder if I can just 'remember' the const reference to the d3dscene once, within a member of the scenegraph class, so I can use it for al the member functions in the scenegraph class who need it (this way not having to pass it over and over again, also giving me cleaner/ better readable code).

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

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

I think a pointer to a reference is illegal.

It's legal, but can cause a lot of issues (particularly if it's a const reference to a temporary; using a pointer is fine as long as the temporary exists, but storing the pointer is a bad idea as the temporary will quickly get destroyed and the pointer invalidated).

@cozzie: You'll need to make sure the pointer is const. You can take the address of the reference and store that just fine. However, beware of temporaries. They will get destroyed and the pointer will then be pointing to invalid memory.

[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
The type of mD3dscene must be const d3drenderer::d3dscene *. It's not a pointer to a reference, but a pointer to the value the reference refers to.

However, with this design, you need to make sure the reference/pointer remains valid through the lifetime of the object. The best way to ensure this is to store a smart pointer. This has a cost, so if you can ensure it by contract, that can be better. On the other hand, explicitly using a smart pointer enforces the object's lifetime guarantee, reducing the potential for present and future code changes to accidentally break the contract creating a hard to trace bug.

Thanks, I'm only assign the mD3dscene once in the implementation and I've made it private.

Not 100% safe, but good enough for now.

I've almost got it working:


// HEADER

class CSceneGraph
{
public:

// code removed

	bool Create(const Crealysm_d3drenderer::CD3dscene *&pD3dscene, const int pLightingEffectId);

private:
	// Pointer to the d3dscene
	const Crealysm_d3drenderer::CD3dscene	*mD3dscene;

// code removed

};

// IMPLEMENTATION

bool CSceneGraph::Create(const Crealysm_d3drenderer::CD3dscene *&pD3dscene, const int pLightingEffectId)
{
	if(!pD3dscene->IsLoaded()) return false;

	if((mD3dscene = pD3dscene) == NULL) return false;

// code removed

}

The only problem is when I call the Create function, I can't get it to work/compile.

First when passing just the const reference I used "Create(*mD3ddev....)" (md3ddev is a pointer), but now it expects a pointer to a const reference:


		if(mSceneGraph.Create(*mD3dscene, 0)) mSceneGraphCreated = true;

Gives the following error:


1>e:\projects\crealysm\crealysm\crealysm_d3d.cpp(600): error C2664: 'Crealysm_renderer::CSceneGraph::Create' : cannot convert parameter 1 from 'Crealysm_d3drenderer::CD3dscene' to 'const Crealysm_d3drenderer::CD3dscene *&'

Any ideas?

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

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

Why not just have your SceneGraph take the scene as a reference in the constructor?


// definition and declaration together for brevity
class CSceneGraph 
{
public:
    SceneGraph(const Crealysm_d3drenderer::CD3dscene& d3dscene)
    : mD3dscene(d3dScene)
    {}	
   
    bool CullLights()
    {
        mD3dscene.DoStuff();
    }
 
private:
    const Crealysm_d3drenderer::CD3dscene& mD3dscene;
 };

sidenote: "CClassName" is redundant. "ClassName" will do just fine.

if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

A) Your code has a reference to a pointer, not a pointer to a reference.

B) Just pass in the pointer. There's no need for a reference.

If the value cannot be null, then it is better to pass a reference. Better to store a reference too, but that's only possible if you pass it in the constructor.

Thanks all. I tried it out as you suggested but no luck yet.


class CSceneGraph
{
public:
	CSceneGraph(const Crealysm_d3drenderer::CD3dscene& d3dScene): mD3dscene(d3dScene)	{ };

private:
	const Crealysm_d3drenderer::CD3dscene& mD3dscene;
}

// initializing the object (in my d3d class member function, loadscene)
if(mSceneLoaded) mSceneGraph = Crealysm_renderer::CSceneGraph(*pD3dscene); 

If I understand correct I know have:

- a const reference to the d3dscene

- which is 'set' through the parameter given with initialization through the constructor

I 'removed' my previous constructor of the CSceneGraph class, don't know yet how I can get 'that back' in the CPP file (implementation), including both my earlier constructor code and setting the const ref.


1>e:\projects\crealysm\crealysm\crealysm_d3d.cpp(61): error C2512: 'Crealysm_renderer::CSceneGraph' : no appropriate default constructor available
1>e:\projects\crealysm\crealysm\crealysm_d3d.cpp(588): error C2582: 'operator =' function is unavailable in 'Crealysm_renderer::CSceneGraph'

Any ideas what I'm overseeing?

Update: I solved the first error by placing "()" after the scenegraph object in my d3d class definition


	Crealysm_renderer::CSceneGraph	mSceneGraph();

The assingment issue / other error not solved yet...

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