Sign in to follow this  
cozzie

Pointer to a const reference?

Recommended Posts

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?

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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?

Edited by cozzie

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Edited by cozzie

Share this post


Link to post
Share on other sites

Found a solution, I concluded that the class where the CSceneGraph is a member of, doesn't have the pointer/reference to the d3dscene (as member initially), so a const reference is out of the question.

 

I therefor now made a const pointer member to the d3dscene in my scenegraph class, which I set in the create call.

So there's only 1 member function left needing the const pointer as function parameter, afterwards all members use the const pointer.

That way the scenegraph member functions can access const members and public variables in the d3dscene class.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this