Sign in to follow this  
Guy Meh

References and const in C++

Recommended Posts

I can never get this straight in C++. Say I have a class A which has a pointer/reference to an object of class B. I want a method in A that can return a reference to this B object. I want to be able to use the B object's methods that modify it, but I do not want to be able to reassign a different B to A. What combination of reference, pointer, and const syntax do I need? So far I have this:
class B
{
    public:
        int value_I_Can_Mess_With;
};

class A
{
    public:
        A(B &newB) : b_ptr(&newB) {} // Does not compile if I make newB const,
                                                            // though it would be better if I did make newB const

        B &getB() const // Should this const be here?
        {
            return *b_ptr;
        }

    private:
        B *b_ptr; // Should this be a reference?
};

...

B myB1, myB2;
A myA(myB1);

myA.getB(). value_I_Can_Mess_With = 10; // Want this to be valid.
myA.getB() = myB2; // Do not want this to be valid.

Share this post


Link to post
Share on other sites

class A { ... }

class B {
const A &a;
public:
B (const A &a) : a (a) {
}
const A &getA () const {
return A;
}
}




--> Has an A, but neither B nor users of B can modify it.

edit: Not to forget: If you have a const-reference as a member field, then you can't return that field as non-const (i.e. relaxing conditions from const to non-const), except using voodoo c++ (i.e. misusing features like const_cast<>()) or returning copies*

* But if the type of the returned value is non-trivial (look for Plain Old Datatype), then the reference on the calling site has to const (afair), there was an issue of Guru of the Week on the latter topic, but better keep off for now ;)



class A { ... }

class B {
A &a;
public:
B (A &a) : a (a) {
}
A &getA () {
return A;
}
const A &getA const () { // still needed under many cicumstances
return A;
}
}




--> Has an A, and every "User" can use and modify it. For some situations you also need to return a const version, e.g. if another class has a const-pointer to an B, than it would be illogical to allow the piped-though A to be modifiable, so you also write the "const A &getA()"-version.


Short answer, though. But maybe what you need.

[Edited by - phresnel on November 13, 2008 9:28:23 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Guy Meh
I want a method in A that can return a reference to this B object. I want to be able to use the B object's methods that modify it, but I do not want to be able to reassign a different B to A.


C++ doesn't work this way. If you can modify something, you can assign to it - unless it's fundamentally unassignable-to (which introduces other problems). This is because assignment doesn't cause A to have "a different" B; it causes A's B to be a copy of the other B.

In short, it's unlikely that you really want to do what you think you want to do, and are trying to make the language behave like Java or something similar (where objects have reference semantics rather than value semantics by default).

Share this post


Link to post
Share on other sites
Hmm.

I think what I basically want is a constant pointer, where I can mess with the object being pointed to but not change the pointer's value.

If I recall, the syntax is this, right?

class A
{
public:
B * const getB() const
{
return b;
}

private:
B *b;
};

Share this post


Link to post
Share on other sites
Unless of course you mean you don't want to be able to change which B A has a reference to, which your code already does. To be able to change A's pointer to a B, A would have to return a pointer to a pointer to a B.

If you do mean you want to modify the returned B but don't want to be able to assign to it, then you should probably re-think what it is you want to do; assigning to B is modifying it, just not using something with 'set' in the name.

EDIT: you got there just before me :) I guess you mean the former then, that you don't want to change A's pointer to B. In which case you needn't worry, since getB returns a B*, which you can do whatever you want, including changing what it's pointing to. It's a copy of A's B*, so the original pointer doesn't get modified at all, only the thing being pointed to.

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