Re: const object declaration
On Dec 5, 7:15 am, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
The following program DOES NOT COMPILE as mentioned earlier in the
beginning of the thread
#include <iostream>
using namespace std;
class X
{
public:
int val;
};
int main()
{
const X obj;
return 0;
}
However the following program COMPILES fine.
#include <iostream>
using namespace std;
class Test
{
public:
Test() { cout << "Test() default ctor" << endl; }
};
class X
{
public:
Test obj;
int val;
};
int main()
{
const X obj;
return 0;
}
I am unable to understand why this program compiles well and the
previous program does not compile.
I was about to say: because in the first example, the default
constructor is trivial (so an initialization is required),
whereas in the second it is not. On re-reading the standard,
however... in =A78.5/9, it says "If no initializer is specified
for an object, and the object is of (possibly cv-qualified)
non-POD class type (or array thereof), the object shall be
default-initialized; if the object is of const-qualified type,
the underlying class type shall have a user-declared default
constructor." According to this, since X does not have a
user-declared default constructor, it shouldn't compile. But it
does, with all three of the compilers at my disposition (g++,
Sun CC and VC++).
I'll admit that this somewhat surprises me. I had always
thought (and apparently, the compilers agree with me) that the
rule was that the class must have a non-trivial default
constructor. Since the (compiler generated) default constructor
for X in the second example is non-trivial, the code would be
OK. Given that three compilers also disagree with what I've
just quoted in the standard, I wonder, too, if there isn't
something else that I've missed.
Thinking about it, I think what the rule should be is: an
initializer is required if the class has no user defined
default constructor, and has one or more sub-objects which have
trivial default constructors. That would allow const instances
without initializers for things like:
struct A
{
virtual void f() ;
} ;
or
struct B
{
std::vector< int > v ;
} ;
. In both cases, all fields are sufficiently initialized (and
it was to allow such things that I thought the rule involved
trivial vs. non-trivial default constructor). And would cause
your second example to fail to compile, since X::val has a
trivial default constructor. (It doesn't cover all cases, of
course. For example:
struct A
{
virtual void f() ; // means default ctor non-trivial.
int i ;
} ;
struct B
{
A a ;
} ;
B const b ;
would still create a const object in which A::i wasn't
initialized.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34