Topic: Explicit call of constructor on object
Author: "Michel Michaud" <micm19@removethis.mail2.cstjean.qc.ca>
Date: 1998/08/06 Raw View
>Seems related to "Is this legal C++". Constructors can't be called
directly -
>destructors can. I've noticed that on some compilers you can construct code
>to call the constructor, but that is non standard C++.
It is related... by accident. From answers to both question, I'd be curious
to
know if it WAS an accepted possibility, just as assignment to this was once
possible and necessary. In fact, what the code seems to do is
*this= String(s.buffer); but of course here it would mean recursion...
My guess is that it was once possible to do both things. That it is
not "Standard C++" is another thing (but could you please tell me where
you see that mentioned in the standard, as I said maybe it's by default ?)
Michel Michaud micm19@mail2.cstjean.qc.ca
http://www3.sympatico.ca/michel.michaud
[ 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: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/08/06 Raw View
>String String::operator=(const String& s) // Could return a ref.
> {
> if (this->length == s.length) // Test for self is
> strcpy(this->buffer, s.buffer); // "unnecessary"...
> else
> {
> this->String::~String(); // Well, maybe...
> this->String::String(s.buffer); // Really ?????
> }
> return *this;
> }
I don't know if it's allowed to call a constructor on an already existing
object, but it surely is not good style and could lead to a memory leak
sometimes.
It is allowed to call the destructor on an existing object, but can be
unsafe if not used properly. Then you can create a new object in place
using one of the constructors through placement new. This is necessary
if you want to copy const data. But I'd still try design my program to
avoid this scenario.
In any case, in the above, one should do something like "delete []buffer"
in place of the destructor call, and "buffer=new char[...]; etc"
instead of the constructor call.
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ 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: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/08/06 Raw View
In article 8018781@news21.bellglobal.com, "Michel Michaud" <micm19@removethis.mail2.cstjean.qc.ca> writes:
>>Seems related to "Is this legal C++". Constructors can't be called
>directly -
>>destructors can. I've noticed that on some compilers you can construct code
>>to call the constructor, but that is non standard C++.
>It is related... by accident. From answers to both question, I'd be curious
>to
>know if it WAS an accepted possibility, just as assignment to this was once
>possible and necessary. In fact, what the code seems to do is
>*this= String(s.buffer); but of course here it would mean recursion...
>
>My guess is that it was once possible to do both things. That it is
>not "Standard C++" is another thing (but could you please tell me where
>you see that mentioned in the standard, as I said maybe it's by default ?)
It has never been valid to call a constructor as if it were a
member function. See for example ARM section 12.1 on constructors.
The standard doesn't say so in as many words, because it uses a
different (and simpler) way to get the same effect: Constructors
don't have names, and so are not found by name lookup. So if
you write for some class T
T t;
T* tp;
t.T(); // or t.T::T()
tp->T(); // or tp->T::T()
the language rules say that you look up the name T in the scope
of class T. Since the constructors for T don't have names and
are not found by name lookup, the last two lines can't result in
a constructor call. Since no member of T could have the name T
other than a constructor, the attempted call cannot be resolved,
and the code doesn't compile.
If you don't qualify the call with a class or object name, but
just write
T();
the code is OK: it creates an anonymous object of type T using
the default constructor. This isn't exactly a constructor call;
it is an object definition which includes, among other things,
invoking a constructor for T. It is unlikely to be what you
want to do, however.
You can get the effect of calling a constructor on an existing
object by using placement-new:
new (&t) T;
new (tp) T;
Whether this is a good idea depends on the circumstances.
---
Steve Clamage, stephen.clamage@sun.com
[ 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: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/08/07 Raw View
Pete Becker <petebecker@acm.org> wrote:
>Michel Michaud wrote:
>> this->String::~String(); // Well, maybe...
>> this->String::String(s.buffer); // Really ?????
>>
>> (BTW the above code does seem to work, at least with one compiler)
>
>It is illegal. Also ill-advised.
It's illegal, but something similar is legal:
this->String::~String();
new(this) String(s.buffer);
It's still ill-advised, for the reason Pete mentioned.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
[ 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: AllanW@my-dejanews.com
Date: 1998/08/07 Raw View
About 3 years ago, I was trying to roll my own container class
and I remember trying this type of thing. It worked on one compiler
at the time, but not on another. Which one was right? I'm 80%
certain that this syntax isn't legal.
However, in a brilliant flash of insight I "discovered" that the
"placement new" operator didn't have to be complicated:
operator new(size_t,void*x) { return x; }
(Yes, I "discovered" this, exactly as if it were a major technique
that I had invented and nobody else knew about. Sometimes, obvious
techniques aren't obvious until the moment they become obvious...)
Anyway, I believe that this is now standard (you don't have to
define this explicitly any more, do you?), and it allows this much
more portable yet totally equivalent code:
new(this) String(s.buffer);
which worked on both compilers 3 years ago, and should work
everywhere today.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: AllanW@my-dejanews.com
Date: 1998/08/07 Raw View
It's also dangerous. You know that member functions with two arguments
are called with more information than the two arguments; there's also
the "this" pointer, plus anything else the compiler vendor thinks is
neccesary. Similarly, the constructor may be called with information
other than the argument list.
For instance, some compiler may try to simplify the new/constructor
sequence by calling operator new from the constructor, if appropriate.
In this case, they must also recognize exceptions where it's NOT
appropriate, such as when the constructor is called with a placement
new or from the constructor of a derived class. Exactly how this work
is implementation derived, which means that there's no portable and
safe way for you to call the constructor directly even if you do get
it's address.
However, using an inline placement-new is pretty darn close to
"directly," and yet it has none of these portability problems.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp Create Your Own Free Member Forum
[ 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: "Michel Michaud" <micm19@removethis.mail2.cstjean.qc.ca>
Date: 1998/08/06 Raw View
When I saw the following code in a book, I was sure it was illegal
(the comments are mine) :
String String::operator=(const String& s) // Could return a ref.
{
if (this->length == s.length) // Test for self is
strcpy(this->buffer, s.buffer); // "unnecessary"...
else
{
this->String::~String(); // Well, maybe...
this->String::String(s.buffer); // Really ?????
}
return *this;
}
I can't find any reference to this construct (explicit call of
constructor on a existing object) in the draft, FAQ or any book.
I know we can't do that in another constructor (where we can't
explicitly call the destructor either), but in another function ?
Normally I'd use a private "Init" function...
So, "by default", is it illegal or legal?
(BTW the above code does seem to work, at least with one compiler)
Michel Michaud, micm19@mail2.cstjean.qc.ca
[ 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: Otto Perdeck <otto.perdeck@inter.NL.net>
Date: 1998/08/06 Raw View
Seems related to "Is this legal C++". Constructors can't be called directly -
destructors can. I've noticed that on some compilers you can construct code
to call the constructor, but that is non standard C++.
Trying to call the constructor for some class T by doing something like T();
will create a temporary object, not call the constructor on the current
object.
-Otto Perdeck
[ 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: Pete Becker <petebecker@acm.org>
Date: 1998/08/06 Raw View
Michel Michaud wrote:
>
> When I saw the following code in a book, I was sure it was illegal
> (the comments are mine) :
>
> String String::operator=(const String& s) // Could return a ref.
> {
> if (this->length == s.length) // Test for self is
> strcpy(this->buffer, s.buffer); // "unnecessary"...
> else
> {
> this->String::~String(); // Well, maybe...
> this->String::String(s.buffer); // Really ?????
> }
> return *this;
> }
>
> I can't find any reference to this construct (explicit call of
> constructor on a existing object) in the draft, FAQ or any book.
> I know we can't do that in another constructor (where we can't
> explicitly call the destructor either), but in another function ?
> Normally I'd use a private "Init" function...
>
> So, "by default", is it illegal or legal?
> (BTW the above code does seem to work, at least with one compiler)
It is illegal. Also ill-advised. Consider what happens if someone
derives a class from this class.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ 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 ]