Topic: Can this be done?


Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 1999/12/21
Raw View
"Michiel Salters" <salters@lucent.com> wrote in message
news:385E6BD2.202F1741@lucent.com...
>
> I'm gonna lie. This won't work.
> If you really, really want to know why this works,
> please explain why you'd need this, so I can answer
> why you don't need it :) .

A good lie. The following change ought to make the original
poster's code work safely for PODs

   void b::operator=(a& a)
   {
      memcpy(static_cast<a*>(this), &a, sizeof(a));
   }

but it is still inferior to

   void b::operator=(a& a)
   {
      *static_cast<a*>(this) = a;
   }

which will work for anything and is almost certain to be
at least as efficient. (I say "at least" because memcpy might
be a byte-wise copy whereas a compiler generated operator=
might know the objects are properly aligned, and use a
word-wise copy, which is faster.)



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Seth Jones <seth@littlebrother.com>
Date: 1999/12/21
Raw View
In article <newscache$5i93nf$xj4$1@firewall.thermoteknix.co.uk>,
K.Hagan@thermoteknix.co.uk says...
>
> "Michiel Salters" <salters@lucent.com> wrote in message
> news:385E6BD2.202F1741@lucent.com...
> >
> > I'm gonna lie. This won't work.
> > If you really, really want to know why this works,
> > please explain why you'd need this, so I can answer
> > why you don't need it :) .
>
> A good lie. The following change ought to make the original
> poster's code work safely for PODs
>
>    void b::operator=(a& a)
>    {
>       memcpy(static_cast<a*>(this), &a, sizeof(a));
>    }
>
> but it is still inferior to
>
>    void b::operator=(a& a)
>    {
>       *static_cast<a*>(this) = a;
>    }
>
Of course, both of these have the same error - "a" is not a typename in
the body of the operator. Does everyone else agree with me that giving a
paramater/variable the same name as a type is a Bad Idea? Of, you could
do
       *static_cast<::a*>(this) = a;
but I still wouldn't advise it.

While I am picking nits, by convention operator= normally returns the
value being assigned, and except in unusual cases the parameter should be
"const".

Seth Jones


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Serial # 19781010 <joerg.amhofer@isagmbh.at>
Date: 1999/12/20
Raw View
How does the compiler handle the memory layout of derived classes?
Are the new members placed behind the inherited ones?

Can I do a memcpy() in this way to provide a simple casting?

(No pointers in both classes, so a simple memcpy should work)


struct a
{
  int i;
}

struct b: struct a
{
  long l;
  void operator=(a& a) { memcpy(this,&a,sizeof(a); }
}

main()
{
  b myB;
  a myA;

 myA.i = 1;
 myB.l = 2;

 myB = myA; // I expect {1,2}
}
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/20
Raw View
Serial # 19781010 wrote:
>
> How does the compiler handle the memory layout of derived classes?
> Are the new members placed behind the inherited ones?

The standard doesn't say. You might be able to find out by checking your
implementation's documentation to find out. Portable code can not make
any assumptions about the matter.

> Can I do a memcpy() in this way to provide a simple casting?

No - you can only safely use memcpy() on POD types (3.9 p2-3).
Inheriting from a base class makes it no longer a POD type (8.5.1). You
should use copy-construction or assignment rather than memcpy(), when
working with non-POD types.


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Michiel Salters <salters@lucent.com>
Date: 1999/12/20
Raw View
Serial # 19781010 wrote:

> How does the compiler handle the memory layout of derived classes?

However it thinks it should be done. There is no hard & simple
rule.

> Are the new members placed behind the inherited ones?

Perhaps, if the phase of the moon doesn't interfere.

> Can I do a memcpy() in this way to provide a simple casting?

No. Use casts.

> struct a {
>   int i; }

> struct b: struct a
> {
>   long l;
>   void operator=(a& a) { memcpy(this,&a,sizeof(a); }
> }

Note that these classes are so-called POD's. They give you
(some) extra guarantees, mostly for C compatibility.
Of course, layout of derived classes isn't something
C worried very much about.

If you want to copy the A part, why not use a::operator=() ?
It is compiler-generated, and perfectly Ok.

> main()
> {
>   b myB;
>   a myA;

>  myA.i = 1;
>  myB.l = 2;

>  myB = myA; // I expect {1,2}
> }

I'm gonna lie. This won't work.
If you really, really want to know why this works,
please explain why you'd need this, so I can answer
why you don't need it :) .

Michiel Salters


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: hawley@ucrmath.ucr.edu (brian hawley)
Date: 3 Oct 90 13:42:29 GMT
Raw View
Suppose I have the following class definition:

class Symbol {
      public:
      int a;       // in real life, this data area more complex
      char b;
      int c;

      Symbol();
      ~Symbol()
      // and others
          }

Now, I want to set up a data area (separate from this), for prefilling
of this data.  In c, this would have been a struture, and I could have
just said: (of course the functions wouldn't be in the structure)
     struct Symbol *temp;

I realize it isn't much extra space, but in c++ you also have the
pointers to the intrinsics, so if I were to "new Symbol", I would
be mallocing extra space for those too.  I would like to avoid
doing that.  My first thought was to do something like:

class Symbol {
      public:
    struct node {
      int a;       // in real life, this data area more complex
      char b;
      int c;
            }
      Symbol();
      ~Symbol()
      // and others
          }

And then try to declare something like "Symbol::node *temp", or other
alternatives along those lines like "symbol = new Symbol();
          symbol->node *temp;"
However, both of those are invalid in c++ delcarations.

What I'm wondering is if there is a way to accomplish what I want, without
having to make a new instance of the class, or having to pull the structure
outside of the class declaration?

Any answers/suggestions?

Please e-mail them to hawley@ucrmath.ucr.edu

Thanks,
Brian


------------------------------------------------------------------------------
Brian N. Hawley                            Internet: hawley@ucrmath.ucr.edu
Dept. of Math & Computer Science           uucp: {ucsd, uci}!ucrmath!hawley
Univ. of Calif., Riverside, CA 92521       phone: (714) 787-4645




Author: shankar@hpclscu.HP.COM (Shankar Unni)
Date: 6 Oct 90 01:42:10 GMT
Raw View
Brian Hawley:

> class Symbol {
>       public:
>     struct node {
>       int a;       // in real life, this data area more complex
>       char b;
>       int c;
>             }
>       Symbol();
>       ~Symbol()
>       // and others
>           }
>
> And then try to declare something like "Symbol::node *temp", or other
> alternatives ...

"Symbol::node *temp" is perfectly valid code with C++ 2.1.
----
Shankar Unni.