Re: Default ctor, etc generated by compiler for structs?
"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:CoidnRcUS_Vgw-nbnZ2dnUVZ_jCdnZ2d@comcast.com...
JohnQ wrote:
"Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
news:guqdnUgq2703oO7bnZ2dnUVZ_j2dnZ2d@comcast.com...
JohnQ wrote:
Are a default constructor, destructor, copy constructor and
assignment operator generated by the compiler for a struct if they
are not explicitely defined?
If by a struct you mean POD, then yes, but only conceptually.
Different from an identical class?
What's "an identical class"? A class with the same order of its
members, all declared public? No difference.
I'm concerned about blasting it around like a C struct. That and keeping the
size the same.
Conceptually how?
Conceptually, every type has a destructor (or you can say that it
does, since you can call it). The standard has s concept of
"a pseudo-destructor call", which means that any type has at least
a pseudo-destructor. In my book you can say that a concept of
a destructor exists for every type.
Understood. That's what the constructor/copy constructor/assignment
operator/destructor do as together: make classes (or structs) behave like
built-in types.
There is no code where the
CPU is led to perform some actions when an object of a POD type is
disposed of, yes. In that sense, a POD type does not have a d-tor.
So, conceptually, yes, physically, no.
See, now I think someone else said that those things would be generated
(maybe they didn't). I had a feeling they weren't. So that's saying
restricting those things in structs is unnecessary.
Hmmm... now if a class is defined just like a struct but has the class'
keyword, will the <whatever you call that group of functions> be generated
always?
If by a struct you mean any class where you only specify data
members, then it depends on the data members.
Lately, I've been pondering, "when does a struct stop being a
struct?". To me, that's when its not the same size as a C struct or
not layed out the same. So obviously, when a virtual function gets
added, then "a struct stops being a struct". I think I can add
non-virtual member functions, non-virtual destructor and operators ad
infinitum and the "struct will still be a struct" (right?).
Nope. If we agree to substitute the words "C struct" with "POD",
then the Standard says that as soon as you add a user-defined c-tor,
it's not a POD any more, so not all non-virtual member functions
are "harmless" as far as POD-ness is concerned.
So I lose all guarantees about the layout and size of thing (it's
implemenation-specific what the thing looks like in memory?)?
Even
though some explicit syntax would make things more evident:
struct A
{
int data;
};
struct B
{
int data;
B(int val){ data = val; } // OK, not virtual
};
Here, 'B' is not a POD class.
OK. So, don't use it like a C struct ever?
class StructWrapper
{
A a_struct;
public:
A(int val){ a_struct.data = val; }
You mean
StructWrapper(int val) { a_struct.data = val; }
, right?
Yes.
operator A&(){ return a_struct; }
};
Where struct B can be used identically to struct A or StructWrapper (I
hope!) as the layouts and sizes are the same (assume the operator is
being used for StructWrapper when I say "can be used identically").
Nothing in the Standard says what the layouts are. We cannot rely on
their being the same.
You see what I'm trying to indicate though right? That I want to be able to
memcpy these things and the like, based upon their size.
sizeof(A)==sizeof(B)==sizeof(StructWrapper)
That doesn't matter.
It was actually a question. And when it deviates from that. The moment I
use 'private' in a struct, all bets are off? Meaning there could be
something tucked between the start of the object in memory and the first
data member?
But a_struct in StructWrapper would have to be made public to
guarantee the same layout as A and B?
Again, there is no way to "guarantee" what's not defined. There is
no definition of a complete class layout in the Standard.
What about a struct with constructor?
What about a struct with just POD data members?
I think the answer is yes, because "there is no difference between a
struct and a class except the public/private access specification"
(and a few minor other things). When I create a class, I always
start by declaring the default constructor, copy constructor and
assignment operator private with no implementation. I don't do that
for structs though (I consider structs like they were in C, but
they really are not in the implementation as far as I know). I'm
thinking that I don't handle structs the same because I trust the
compiler to do the right thing in the case of structs whereas
bitwise copy for a class may not be what is desired, for example.
What's "bitwise copy"? I don't know of that concept in C++.
The equivalent of doing a memcpy of the class or struct (whether I
used the right terminology or not I don't know... "bytewise" seems
more appropriate).
Well, calling 'memcpy' upon copy-constructing an object is up to the
implementation. There is no way to know exactly what they do with
POD, most likely 'memcpy', or 'memmove', or some such. However, it
would be safer to assume that "memberwise copy" is performed, which
means that copy semantics for each member (provided they exist) are
invoked.
OK. Someone else said that memberwise copy was done.
Is the above reasoning OK? Should I continue NOT declaring/defining
the default stuff for structs?
It's up to you. And the ability of the compiler to generate the
functions you don't declare/define depends on the data members.
OK, so from what I gather, the compiler may or may not generate the
functions/operators depending on the data members. Is it that if
there is any non-POD data member, then the functions/operators get
generated? Is it always the full set (?): default constructor, copy
constructor, assignment operator, (destructor?).
No, not always. For example, it's possible to copy-construct
a reference, but it's not possible to assign one, so if your class
has a data member that is a reference (it does make it non-POD, BTW),
then the copy c-tor can (and will) be generated but the copy
assignment op cannot (and will not) be.
That's getting away from "struct with only POD data members", and that is
what I'm really only concerned with.
John