 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Keshav Guest
|
Posted: Tue Sep 20, 2005 1:57 pm Post subject: How Constructor of typedef class works |
|
|
typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
If valid then how does compiler create a cosutructor for this class
How can i write overloaded constructor for it?
Wht will be the behavior if i inherit some classs from it?
Thanks in advance
Keshav
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Wed Sep 21, 2005 12:02 am Post subject: Re: How Constructor of typedef class works |
|
|
Keshav wrote:
| Quote: | typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
|
Both, IMHO. You define an anonymous class and then use a typedef to assign
an alias to it. This is valid, but what is the point?
| Quote: | If valid then how does compiler create a cosutructor for this class
|
How it does so is up to the compiler. After all, a ctor is only some code
that is invoked in specific places.
| Quote: | How can i write overloaded constructor for it?
|
Well, now that is something which you can't because the ctor always has the
same name as the class, but you class doesn't have a name.
| Quote: | Wht will be the behavior if i inherit some classs from it?
|
In the derived class, you will have access to the base via the typedef. This
doesn't mean that you can add anything there (as usual) but at least you
have a name.
Uli
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Wed Sep 21, 2005 12:11 am Post subject: Re: How Constructor of typedef class works |
|
|
Keshav <gupta.keshav (AT) gmail (DOT) com> wrote:
| Quote: | typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
|
It's both - that is, it's legal, but not a good idea. "typedef struct
.... A;" is sometimes useful for compatibility with C, but the "class"
keyword doesn't exist in C.
| Quote: | If valid then how does compiler create a cosutructor for this class
|
The same way it implicitly defines constructors for other classes
that have them, I suppose.
| Quote: | How can i write overloaded constructor for it?
|
You can't, because the constructor must be declared inside the class
definition using the class name, and the class doesn't get a name
until after its definition.
| Quote: | Wht will be the behavior if i inherit some classs from it?
|
I don't know and I don't really care.
--
Ben Hutchings
Having problems with C++ templates? Your questions may be answered by
<http://womble.decadentplace.org.uk/c++/template-faq.html>.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Wed Sep 21, 2005 9:07 am Post subject: Re: How Constructor of typedef class works |
|
|
Keshav wrote:
| Quote: | typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
If valid then how does compiler create a cosutructor for this class
How can i write overloaded constructor for it?
Wht will be the behavior if i inherit some classs from it?
Thanks in advance
Keshav
|
It may be instructive to decompose the statement into its inner and
outer parts. The inner construct would be:
class
{
int i;
int j;
};
In short, it's a declaration for an unnamed class. "Unnamed" means that
the declaration has not reserved a symbol which could then refer to
this class type in subsequent declarations and statements. But even
though no visible name for this class type has been created, the
compiler has assigned it name on its own. The compiler names every
declared type that it encounters. The compiler's name for this class
would be the class's non-visible, or "internal" name. The internal name
would be the name used for compiler-provided default or copy
constuctors.
The enclosing typedef declaration effectively reserves a symbol, A, for
the compiler's internal name for this class type. The typedef for all
practical purposes becomes the visible name for the unnamed class.
This kind of typedef idiom is common in C as a way of being able to
reference struct types without having to provide the "struct" keyword.
But in C++, this typedef layer has little practical value. Classes and
structs are first-class citizens in C++, their names can be appear in
source code on their own. Therefore the C++ way of declaring the
example class would be:
class A
{
int i;
int j;
};
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
mlimber Guest
|
Posted: Wed Sep 21, 2005 9:08 am Post subject: Re: How Constructor of typedef class works |
|
|
Keshav wrote:
| Quote: | typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
If valid then how does compiler create a cosutructor for this class
How can i write overloaded constructor for it?
Wht will be the behavior if i inherit some classs from it?
|
That's valid syntax, but the typedef is unnecessary and unidiomatic in
C++. The compiler will generate a default constructor that does
nothing, so you could also do this without generating errors:
class B : public A
{
B() : A() {}
};
Of course, if you omit the call to A::A(), you'll get the same result
(i.e., the compiler will call the default constructor for the base
class A). Also, the class A is nearly useless as written because
nothing can access the members i and j, though you could still refer to
an object of type B with a pointer to A. As for your penultimate
question, you can write your own constructor in the usual way (cf. the
constructor B::B()).
Cheers! --M
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Wed Sep 21, 2005 9:10 am Post subject: Re: How Constructor of typedef class works |
|
|
Ulrich Eckhardt wrote:
| Quote: | Keshav wrote:
typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
Both, IMHO. You define an anonymous class and then use a
typedef to assign an alias to it. This is valid, but what is
the point?
|
That isn't quite true. There is a special rule for this case,
which says (§7.1.3/5) "If the typedef declaration defines an
unnamded class (or enum), the first typedef-name declared by teh
declaration to be that class type (or enum type) is used to
denote the class type (or enum type) for linkage purposes only.
The class isn't really anonymous.
The reason for this rule is, of course, C compatibility.
Suppose you include a header with something like:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct { int a; int b; } S ;
#ifdef __cplusplus
}
#endif
Without the special rule, the struct would be a different type
in every translation unit, and an "f( S* )" in one translation
unit would not match and "f( S* )" in another.
| Quote: | If valid then how does compiler create a cosutructor for
this class
How it does so is up to the compiler. After all, a ctor is
only some code that is invoked in specific places.
|
Or no code, if, as is the case here, the constructor is trivial.
| Quote: | How can i write overloaded constructor for it?
Well, now that is something which you can't because the ctor
always has the same name as the class, but you class doesn't
have a name.
|
The class has a name, but only for linkage purposes. Which
isn't sufficient for naming a constructor.
I imagine that the intent of the restriction was simply to avoid
requiring unlimited look-ahead for the compiler to know that it
was dealing with a constructor (and that the absense of a return
type was a requirement, and not an error).
At any rate, as mentionned above, the motivation behind all this
is C compatibility -- to allow you to write headers which can be
used for both C and C++, or even to use pure C headers, provided
you encapsulate them in an extern "C" { ... }. Obviously,
support for constructors is not an issue in such cases.
| Quote: | Wht will be the behavior if i inherit some classs from it?
In the derived class, you will have access to the base via the
typedef. This doesn't mean that you can add anything there (as
usual) but at least you have a name.
|
I think it's actually a very common idiom. You use a C library,
which provides the struct's. You wrap them by deriving, and
only accessing the derived class. Except when passing the
object to the library interface, when the implicit convertion to
base means that the library sees the original C struct.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Meador Inge Guest
|
Posted: Wed Sep 21, 2005 9:14 am Post subject: Re: How Constructor of typedef class works |
|
|
Keshav wrote:
| Quote: | typedef class {
int i;
int j;
} A;
Is it a valid syntax or misuse of tyedef?
It is valid. |
| Quote: | If valid then how does compiler create a cosutructor for this class
The compiler generates default constructors for the class. |
| Quote: | How can i write overloaded constructor for it?
I don't think you can. Per 12.1.3 of the C++ Standard: "A typedef-name |
that names a class is a class-name (7.1.3); however, a typedef-name
that names a class shall not be used as the identifier in the
declarator for a constructor declaration.". Now this just says you
can't use the typedef-name to name the constructor, but I don't know
what other name you would use. So, I am assuming it can't be done since
there is no other name beside the typedef-name to reference the class
by.
| Quote: | Wht will be the behavior if i inherit some classs from it?
I would think it would be the same as inheriting from a normally |
(meaning 'class name {};', no typedef) defined class.
I would suggest just using:
class A
{};
instead of:
typedef class {} A;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler Guest
|
Posted: Wed Sep 21, 2005 12:09 pm Post subject: Re: How Constructor of typedef class works |
|
|
Hello James Kanze,
| Quote: | I think it's actually a very common idiom. You use a C library,
which provides the struct's. You wrap them by deriving, and
only accessing the derived class. Except when passing the
object to the library interface, when the implicit convertion to
base means that the library sees the original C struct.
|
One of the nasty side effects of this idiom is, that it is impossible
to declare such an entity w/o definition. The usual way to do that,
i.e.:
// fwd header
struct S;
// definition header
struct S {
....
};
does not work here:
struct S;
typedef struct { int a; int b; } S ;
must envoke an compiler error.
Greetings from Bremen,
Daniel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Allan W Guest
|
Posted: Thu Sep 22, 2005 9:10 am Post subject: Re: How Constructor of typedef class works |
|
|
Keshav wrote:
| Quote: | typedef class {
int i;
int j;
} A;
|
Nobody has mentioned the REASON for this idiom, except to
say "C compatibility."
I wasn't part of the standardization committee, but the
reason seems pretty obvious:
In C, if you declare a structure this way:
struct ABC {
int i;
int j;
};
then whenever you instantiate it, you have to use the
keyword "struct":
struct ABC abc1;
| Quote: | From the earliest days of C++, that restriction was
lifted: you can use ABC as a type name: |
ABC abc2;
But if you wanted to accomplish that in C, you had to
use a typedef. So two idioms became popular. One idiom
was to use a name for the typedef, and another name for
the structure (usually with the "Tag" suffix):
typedef struct ABC_Tag {
int i;
int j;
} ABC;
ABC abc3;
You only needed the name ABC_Tag if you did something
like a linked list, though... where the structure
contained a pointer to another instance of the same
structure. Other than that, the name wasn't used at all,
which is why some people started leaving it out altogether:
typedef struct {
int i;
int j;
} ABC;
ABC abc4;
Now... as someone else pointed out, C doesn't have the
keyword "class", so your original example wouldn't be
valid. I can imagine someone who knows C very well, but
is new to C++, using this type of typedef even for classes.
typedef class {
public: // So that not all members are private!
int i;
int j;
} ABC;
ABC abc5;
But once you accept that this isn't valid in C, there is
no longer *any* advantage over the more normal form:
class ABC {
public: // Needed, so that not all members are private!
int i;
int j;
};
ABC abc6;
And, as everyone here has noted, this form allows you to
use the class name within the class -- for instance, to
declare a constructor.
HTH
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Sep 22, 2005 9:17 am Post subject: Re: How Constructor of typedef class works |
|
|
Daniel Krügler wrote:
| Quote: | Hello James Kanze,
I think it's actually a very common idiom. You use a C
library, which provides the struct's. You wrap them by
deriving, and only accessing the derived class. Except when
passing the object to the library interface, when the
implicit convertion to base means that the library sees the
original C struct.
One of the nasty side effects of this idiom is, that it is
impossible to declare such an entity w/o definition.
|
Which such an entity? There's no problem with the derived class
whatsoever. And the only place in C++ code that you use the C
struct is as a base class, a use which requires a complete
definition anyway.
| Quote: | The usual way to do that, i.e.:
// fwd header
struct S;
// definition header
struct S {
...
};
does not work here:
struct S;
typedef struct { int a; int b; } S ;
must envoke an compiler error.
|
I'm not sure about that -- if the two declarations are in
different translation units, there should be no problem. And
§7.1.3/2 says that "In a given scope, a typedef specifier can be
used to redefine the name of any type declared in that scope to
refer to the type to which it already refers"; to tell the
truth, I don't know whether that would apply here or not.
It's true that the above may represent a flaw in the idiom, in
so far as it means that some legal C code isn't legal C++. In
C++, in your example, either the code is illegal, or both S
refer to the same struct. In C, the code is legal, but the two
S refer to totally different entities. In C, something like:
struct S { int a ; int b ; } ;
typedef double S ;
is legal -- you use "struct S" to refer to the first, and just
plain "S" to refer to the second.
I don't think you can do anything like this in C++. On the
other hand, I've never seen any C code which actually did it
either; whenever a struct tag has had the same name as a
typedef, the typedef has been to that struct. Which is a usage
C++ supports.
And of course, if the goal is to forward declare S in C, you
would have to write something like:
struct S ;
typedef struct S { int a; int b; } S ;
or
typedef struct S S ;
struct S { int a; int b; } ;
Both of which are also legal in C++ (because of special rules
like the one I cited above), with the same semantic as in C.
Note that these rather strange rules are there precisely to
accomodate C and common C/C++ headers. It's generally
considered bad style, I think, to write pure C++ code which
depends on them.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Daniel Krügler Guest
|
Posted: Thu Sep 22, 2005 2:38 pm Post subject: Re: How Constructor of typedef class works |
|
|
kanze wrote:
| Quote: | Daniel Krügler wrote:
One of the nasty side effects of this idiom is, that it is
impossible to declare such an entity w/o definition.
Which such an entity? There's no problem with the derived class
whatsoever. And the only place in C++ code that you use the C
struct is as a base class, a use which requires a complete
definition anyway.
|
Colleagues of mine and I myself stumbled about that restriction
in case of the not so rare situation, that you want to combine
handle-body idiom for better seperation of declaration and
implementation combined with C/C++ interaction. A typical situation was
// C_Impl header, actually only for implementation needed but contains
// lots of stuff besides the pure forward declaration
#ifdef __cplusplus
extern "C" {
#endif
.... lots of stuff
// This is interesting:
typedef struct { int a; int b; } S ;
#ifdef __cplusplus
}
#endif
// CPP_H: C++ header for public use
extern "C" struct S; // That hurts!
class ForAll {
S* pimpl;
...
};
// Impl of C++ code:
#include "C_Impl.h"
#include "CPP_H.h" // "Invalid redeclaration of S"
Of course this could have been prevented by a further indirection,
but a direct declaration of S would have been nice here...
| Quote: | I'm not sure about that -- if the two declarations are in
different translation units, there should be no problem.
|
Yes, because of the linkage name guarantee, right?
| Quote: | And
§7.1.3/2 says that "In a given scope, a typedef specifier can be
used to redefine the name of any type declared in that scope to
refer to the type to which it already refers"; to tell the
truth, I don't know whether that would apply here or not.
|
I read the same clause and I am not so sure either concerning all its
implications, but I think, that only allows constructions like
typedef S S;
which is not very useful in the scenario mentioned above, because this
typedef requires a (visible) previous definition of S.
All compilers I have available here, choke in case of this as an
invalid redeclaration.
| Quote: | And of course, if the goal is to forward declare S in C, you
would have to write something like:
struct S ;
typedef struct S { int a; int b; } S ;
or
typedef struct S S ;
struct S { int a; int b; } ;
Both of which are also legal in C++ (because of special rules
like the one I cited above), with the same semantic as in C.
|
That is true, of course. But I was thinking of using a 3rd party
API header which I am not supposed to modify...
Greetings,
Daniel
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Sep 23, 2005 10:23 pm Post subject: Re: How Constructor of typedef class works |
|
|
Daniel Krügler wrote:
| Quote: | kanze wrote:
Daniel Krügler wrote:
One of the nasty side effects of this idiom is, that it is
impossible to declare such an entity w/o definition.
Which such an entity? There's no problem with the derived
class whatsoever. And the only place in C++ code that you
use the C struct is as a base class, a use which requires a
complete definition anyway.
Colleagues of mine and I myself stumbled about that
restriction in case of the not so rare situation, that you
want to combine handle-body idiom for better seperation of
declaration and implementation combined with C/C++
interaction. A typical situation was
// C_Impl header, actually only for implementation needed but contains
// lots of stuff besides the pure forward declaration
#ifdef __cplusplus
extern "C" {
#endif
... lots of stuff
// This is interesting:
typedef struct { int a; int b; } S ;
#ifdef __cplusplus
}
#endif
// CPP_H: C++ header for public use
extern "C" struct S; // That hurts!
class ForAll {
S* pimpl;
...
};
// Impl of C++ code:
#include "C_Impl.h"
#include "CPP_H.h" // "Invalid redeclaration of S"
Of course this could have been prevented by a further
indirection, but a direct declaration of S would have been
nice here...
|
I don't see what is wrong with a C++ class Impl which derives
from S. In fact, I would rather prefer that solution; it would
allow adding e.g. member functions to the Impl. (In general, I
like keeping the C and C++ as well separated as possible. As
the implementation class in complilation firewall idiom is
definitly a C++ idiom, I rather prefer that it be a C++ class.)
| Quote: | I'm not sure about that -- if the two declarations are in
different translation units, there should be no problem.
Yes, because of the linkage name guarantee, right?
|
That's my interpretation.
To tell the truth, this is a part of the standard I've never
really considered in detail. In pure C++ code, I ignore it; it
just isn't there, as far as I'm concerned. And in mixed code,
it's always worked for me, as it is.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|