Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

About C++ classes with self reference

I am a little bit confused ...

Why is this allowed in C++:

static int t = 0;

class A
{
    public:
        A() : m(t++)
        {

            cout << "C:" << m << endl; 
            if(t >= 5)
            {
                A a;                      // <<<< ----- THIS line
                throw( a);
            }
        }            

        int m;
};

But this not:

static int t = 0;

class A
{
    public:

        A() : m(t++)
        {

            cout << "C:" << m << endl; 
        }

        A a;                            // <<<< ----- THIS line

        int m;
};

The second one is not compiling as expected (yes, I know why it's not compiling: at that point in code the A is still incomplete) ...

But ... the first one compiles nicely (and does what it's supposed to do, ie: crashes the application on a statement like: A a[10]; ). Is the A a complete type in the constructor? Can also point me some C++ standard entries for this situation?

like image 786
Ferenc Deak Avatar asked Mar 19 '14 13:03

Ferenc Deak


2 Answers

When you are declaring any variable, compiler should know the size of that. in case of your second example you are creating an object of A inside A so compiler will not be able to calculate the size of A to allocate memory.

like image 51
rajenpandit Avatar answered Oct 08 '22 11:10

rajenpandit


Can also point me some C++ standard entries for this situation?

Yes, the draft C++ standard says a class is not completely defined until the closing }, this is in section 9.2 Class members paragraph 2:

A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the classspecifier. [...]

and all non-static data members of a class must be complete, from paragraph 9:

Non-static (9.4) data members shall not have incomplete types. In particular, a class C shall not contain a non-static member of class C, but it can contain a pointer or reference to an object of class C.

but it is considered complete within the constructor also within paragraph 2:

[...]Within the class member-specification, the class is regarded as complete within function bodies, default arguments,[...]

although static members can be incomplete, section 9.4.2 Static data members paragraph 2:

The declaration of a static data member in its class definition is not a definition and may be of an incomplete type other than cv-qualified void.[...]

It also makes sense to not allow a class to contain itself since this would require infinite space since the self reference would never end, A contains A which contains A ...

like image 3
Shafik Yaghmour Avatar answered Oct 08 '22 11:10

Shafik Yaghmour