On May 21, 3:10 am, "Ole Nielsby" <ole.niel...@tekare-you-
spamminglogisk.dkwrote:
James Kanze <james.ka...@gmail.comwrote:
Ole Nielsby <ole.nielsby@tekare-you-a-spammer?logisk.dkwrote:
I want to create (with new) and delete a forward declared class.
You can't. The type must be complete before the new expression.
[...]
I stuffed it in a dummy template:
---code begin---
class Zorg_implementation; //to be defined by another library
template <typename Zclass Zorg_t {
public:
Zorg_t(): zi(new Z) {}
~Zorg_t() {delete zi;}
private:
Z *zi;};
typedef Zorg_t<Zorg_implementationZorg;
---code end---
[typo corrected]
If you never actually instantiation a Zorg, the constructor is
never instantiated, and there is no problem. If whenever you
create an instance of Zorg, Zorg_implementation has been fully
defined, there is also no problem. Otherwise, you will
encounter the same problem as above.
Well, that's the funny thing. I declare, define and use a static Zorg
instance in a static library that is compiled without ever defining
the Zorg_implementation.
That is strange. Formally, until you actually finish linking,
you are still "compiling", and compiler can (and some do) defer
instantiation until link time (and the code isn't linked when
you build a static library). Doing so systematically, today, is
very rare, however, and all of the compilers I use regularly
will attempt instantiation at compile time, if the definition is
available (which it is here). And there is no doubt that "new
Zorg_implementation" is illegal if Zorg_implementation is an
incomplete type, and every compiler I know will complain about
it.
[...] you will only get a compiler error if you try to actually
create an instance of Zorg at a point where Zorg_implementation
has not been fully defined.
VC8 allows just that. Though I guess it's not standard-compliant;
there seems to be an agreement here that the template instantiation
should do the same as if I had defined the stuff non-templatewise
at the point of the template instantiation.
I'm not sure with regards to standard compliance; it might be
undefined behavior when a template is involved. But I couldn't
reproduce your symptoms with any of the compilers I have at
hand, including VC8. All of them compiled the code above
without problems, of course, because there was no instantiation.
But with all of them, including VC8, I get an error message if I
add the line:
Zorg aZorg ;
at the end. So either you're actually doing something
different, and I've misunderstood what you're trying, or you're
using some special options with VC8 (in addition to the ones you
need to compile any C++, like /vmg /GR /EHs).
(I suspect the VC8 compiler for being "infected" with .NET
generics under the hood... perhaps the compiler tries to reduce
templates to CLR generics, and deduces from the code that the
template argument should have a 'new' constraint. But this is
pure off-topic speculation.)
That's not the case with the free, downloadable version, at
least with the command line options I use. I'd almost be
willing to bet that either you've actually furnished a
definition of Zorg_implementation, or more likely, that you've
not done anything to trigger instantiation of the template.
(Note that just declaring an instance, without defining it, or
defining a pointer to an instance, does not trigger
instantiation.)
--
James Kanze (GABI Software) email:ja*********@gmail.com
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