views:

648

answers:

5

I've run into an issue I don't understand and I was hoping someone here might provide some insight. The simplified code is as follows (original code was a custom queue/queue-iterator implementation):

class B
{
public:
    B() {};
    class C
    {
    public:
        int get();
        C(B&b) : b(b){};
    private:
        B& b;
    };
public:
    C get_c() { return C(*this); }
};

int main()
{
    B b;
    B::C c = b.get_c();


    c = b.get_c();
    return EXIT_SUCCESS;
}

This, when compiled, gives me the following error:

foo.cpp: In member function 'B::C& B::C::operator=(const B::C&)':
foo.cpp:46: error: non-static reference member 'B& B::C::b', can't use default assignment operator
foo.cpp: In function 'int main()':
foo.cpp:63: note: synthesized method 'B::C& B::C::operator=(const B::C&)' first required here

I can go around this by using two separate C variables, as they are supposed to be independent 'C' objects, but this only hides the problem (I still don't understand why I can't do this).

I think the reason is that the reference cannot be copied, but I don't understand why. Do I need to provide my own assignment operator and copy constructor?

+6  A: 

A reference cannot be changed after being given its initial value. This means that it is impossible to write an assignment operator that changes the value of a reference member. If you need to do this, use a pointer instead of a reference.

interjay
It's actually possible. Check my comment below for details.
rmn
+9  A: 

Laura,

This problem has nothing to do with inner classes. In C++ you just can't (re)assign references - they need to be initialised when defined.

A simpler example is:

class B
{
public:
    B(int& i) : ir(i) {};

    int& ir;
};


int main()
{
    int i;
    B b(i);      // Constructor - OK

    int j;
    B bb = B(j); // Copy constructor - OK

    bb = b;      // Assignment - Error
    return 0;
}
Seb Rose
Bah, of course you're correct, I can't believe I missed the obvious explanation. Should have had more coffee in the morning :D
laura
+1. I find that habitually using "bind" rather than "assign" when talking about references helps me from making this mistake.
Kaz Dragon
A: 

C++ doesn't have "inner classes", just nested class declarations. "inner classes" are a Java-ism that I don't think are found in other mainstream languages. In Java, inner classes are special because they contain an implicit immutable reference to an object of the containing type. To achieve the equivalent to C++'s nested declarations in Java requires use of static inner classes; static inner classes do not contain a reference to an object of the declaring type.

DrPizza
+1  A: 

Actually, there's a solution to this. You can implement operator= in terms of copy construction, and it will work :) It's a very capable technique for such cases. Assuming you do want to support assignment.

rmn
Calling a destructor in an assignment operator is a very bad progamming habit.
Sjoerd
A: 

HI, c++ is also having inner classes which can be used in exception mechanism.in java i understand it is used widely.in c++ it is used in case of need like exception throwing mechanism and for debugging purposes

saravanan M