C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Returntyp von Operator new und Arrays

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Marcel Müller
Guest





PostPosted: Sat Feb 04, 2006 11:00 pm    Post subject: Returntyp von Operator new und Arrays Reply with quote



Hallo!

Kann man mit dem new-Operator eigentlich auch Arrays als logischen Typ
allozieren?

Also in C++ gibt es ja auch Array-Typen mit zur Compilezeit bekannter Größe:

typedef int my_type[5];

void foo(my_type* array); // bindet nur an int(*)[5]

Wenn ich aber new my_type schreibe, wird offenbar int* zurückgeliefert
und nicht my_type*. Die Array-Eigenschaft geht verloren.

Folglich gelingt der Aufruf der Funktion foo in der folgenden Zeile nicht:

foo(new my_type); // Fehler
// Sinngemäß: Kann int* nicht in int (*)[5] konvertieren.

Das wäre das Verhalten, wenn der new[] Operator verwendet wird, bei dem
die Größe des Arrays erst zur Laufzeit bekannt ist.

Schön und gut, aber wie Alloziere ich denn nun /ein/ Objekt von Typ int[5]?

Hintergrund: die Funktion foo ist eingetlich ein Template der Art:

template <typename T, size_t S>
void foo(T (*)[S]);

Das bietet allerlei Möglichkeiten, da die Größe des Arrays nun zur
Compilezeit bekannt ist und auch bleibt.


Natürlich kann ich jetzt eine Proxy-Klasse um den Typ herum schreiben
und allerlei Operatoren überladen, um das Problem zu umgehen. Aber
irgendwie scheint mir das abwegig und lästig.
Vor allem wird das dann ein schwer zu umgehendes Problem, wenn der
Arraytyp selbst an einen Template-Typ T2 irgendeiner Klasse bindet und
die Implementation vernünftigerweise erwartet, dass eine Funktion
foo(T2*) mit foo(new T2) aufgerufen werden kann.


Irgendwelche Ideen?
Mache ich da etwas falsch?
Hat mein Compiler (im Moment gcc 3.3.5) einen Schlag?


Marcel

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
kanze
Guest





PostPosted: Tue Feb 07, 2006 2:03 pm    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote



Marcel Müller wrote:

Quote:
Kann man mit dem new-Operator eigentlich auch Arrays als
logischen Typ allozieren?

Kann man, soll man in Allgemein aber nicht.

Quote:
Also in C++ gibt es ja auch Array-Typen mit zur Compilezeit
bekannter Größe:

typedef int my_type[5];

void foo(my_type* array); // bindet nur an int(*)[5]

So weit hat's immer gegeben. Auch in C.

Vorsicht aber. Typischerweise wird so eine Funktion für zwei
dimensionnalen Arrays verwendet. So ungefähr:

my_type array[ 20 ] ;
foo( array ) ;

Quote:
Wenn ich aber new my_type schreibe, wird offenbar int*
zurückgeliefert und nicht my_type*. Die Array-Eigenschaft geht
verloren.

Mehr oder weniger. C-artige Arrays sind nicht normalle Typen.
Wenn du einen allokierst, bekommst du nicht einen Zeiger auf dem
Array, sondern einen Zeiger auf seinem ersten Element. Um einen
my_type* von new zu bekommen, musst du etwas wie "new
my_type[1]" schreiben.

Quote:
Folglich gelingt der Aufruf der Funktion foo in der folgenden
Zeile nicht:

foo(new my_type); // Fehler
// Sinngemäß: Kann int* nicht in int (*)[5] konvertieren.

Das wäre das Verhalten, wenn der new[] Operator verwendet
wird, bei dem die Größe des Arrays erst zur Laufzeit bekannt
ist.

Schön und gut, aber wie Alloziere ich denn nun /ein/ Objekt
von Typ int[5]?

new my_type[1]

Es geht nicht anders (auf historischen Grunden).

Quote:
Hintergrund: die Funktion foo ist eingetlich ein Template der Art:

template <typename T, size_t S
void foo(T (*)[S]);

Das bietet allerlei Möglichkeiten, da die Größe des Arrays nun
zur Compilezeit bekannt ist und auch bleibt.

Natürlich kann ich jetzt eine Proxy-Klasse um den Typ herum
schreiben und allerlei Operatoren überladen, um das Problem zu
umgehen. Aber irgendwie scheint mir das abwegig und lästig.

Ich wurde std::vector statt C-artige Arrays benutzen.

Quote:
Vor allem wird das dann ein schwer zu umgehendes Problem, wenn
der Arraytyp selbst an einen Template-Typ T2 irgendeiner
Klasse bindet und die Implementation vernünftigerweise
erwartet, dass eine Funktion foo(T2*) mit foo(new T2)
aufgerufen werden kann.

Irgendwelche Ideen?
Mache ich da etwas falsch?

C-artige Arrays benutzen? :-)

Quote:
Hat mein Compiler (im Moment gcc 3.3.5) einen Schlag?

Nein. Die Sprache aber wohl.

--
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

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Marcel Müller
Guest





PostPosted: Sat Feb 18, 2006 10:06 pm    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote



kanze wrote:
Quote:
Marcel Müller wrote:
Schön und gut, aber wie Alloziere ich denn nun /ein/ Objekt
von Typ int[5]?

new my_type[1]

Es geht nicht anders (auf historischen Grunden).

OK, nicht schön, aber selten.

Die unangenehme Nebenwirkung ist, dass dabei immer der operator new[]
aufgerufen wird und konsequenterweise das Objekt auch mit delete[]
freigegeben werden muss.


Quote:
Natürlich kann ich jetzt eine Proxy-Klasse um den Typ herum
schreiben und allerlei Operatoren überladen, um das Problem zu
umgehen. Aber irgendwie scheint mir das abwegig und lästig.

Ich wurde std::vector statt C-artige Arrays benutzen.

In diesem Fall ungern, denn dann kann ich keine Spezialisierungen für
Trivialfälle mehr machen.


Marcel

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Bob Hairgrove
Guest





PostPosted: Sat Feb 18, 2006 11:06 pm    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote

On Sat, 18 Feb 2006 23:03:11 +0100, Marcel Müller
<news.5.maazl (AT) spamgourmet (DOT) org> wrote:

Quote:
In diesem Fall ungern, denn dann kann ich keine Spezialisierungen für
Trivialfälle mehr machen.

Was für Trivialfälle, und warum überhaupt spezialisieren?

--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Marcel Müller
Guest





PostPosted: Sun Feb 19, 2006 11:06 am    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote

Bob Hairgrove wrote:
Quote:
In diesem Fall ungern, denn dann kann ich keine Spezialisierungen für
Trivialfälle mehr machen.

Was für Trivialfälle, und warum überhaupt spezialisieren?

Mathematisches Zeugs, wie z.B. 2*2 Matrix-Inversion (real, komplex).

Ausserdem möchte ich zur Compilezeit sicherstellen, dass bestimmten
Funktionen nur Arrays einer bestimmten Größe übergeben werden können.

Das Ganze ist natürlich im Kontext von Smart-Arrays zu sehen, die im
Wesentlichen auf boost::shared_array aufsetzen, selbige aber funktionell
deutlich erweitern. Da tritt das Problem aufgrund der zusätzlichen
Kapselung natürlich zunächst mal nicht auf. Aber es gibt Schnittstellen,
in denen die die Array-Typen nativ auftreten. Beispielsweise könnte man,
wenn die Arraygröße im Returnwert von new noch enthalten ist, eine
Template-Funktion schreiben, die sowohl den Datentyp als auch die Größe
automatisch aus dem Funktionsargument herausdestilliert. Also so, dass
folgender Ausdruck funktioniert:

template<typename T, size_t S>
void my_array_factory(T (*r)[S]);

my_array_factory(new int[3]); // geht natürlich nicht!

my_array_factory(new int[3][1]); // Workaround von James Kanze


Die Idee dahinter ist letztlich immer dieselbe, den Luxus von C++ mit
der Geschwindigkeit von C zu vereinen. Oft geht das mittlerweile ganz
gut. Und die Zahl der (unbemerkten) Programmierfehler hat nach meiner
Erfahrung dabei /deutlich/ abgenommen.


Marcel

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Tobias Güntner
Guest





PostPosted: Sun Feb 19, 2006 2:13 pm    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote

Marcel Müller wrote:
Quote:
typedef int my_type[5];
....
Schön und gut, aber wie Alloziere ich denn nun /ein/ Objekt
von Typ int[5]?

new my_type[1]

Es geht nicht anders (auf historischen Grunden).

OK, nicht schön, aber selten.

Die unangenehme Nebenwirkung ist, dass dabei immer der operator new[]
aufgerufen wird und konsequenterweise das Objekt auch mit delete[]
freigegeben werden muss.

Bei "new my_type;" doch ebenso, man muss also in jedem Fall delete[]
verwenden. Oder habe ich da jetzt etwas falsch verstanden?

Gruß
Tobias

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
kanze
Guest





PostPosted: Mon Feb 20, 2006 2:06 pm    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote

Tobias Güntner wrote:
Quote:
Marcel Müller wrote:
typedef int my_type[5];
...
Schön und gut, aber wie Alloziere ich denn nun /ein/ Objekt
von Typ int[5]?

new my_type[1]

Es geht nicht anders (auf historischen Grunden).

OK, nicht schön, aber selten.

Die unangenehme Nebenwirkung ist, dass dabei immer der
operator new[] aufgerufen wird und konsequenterweise das
Objekt auch mit delete[] freigegeben werden muss.

Bei "new my_type;" doch ebenso, man muss also in jedem Fall
delete[] verwenden. Oder habe ich da jetzt etwas falsch
verstanden?

Soweit ich weiß, hast du richtig verstanden. Es gibt zwei Art
von new, scalar new und array new. Und die Art wird vom Typ
gewählt, und nicht von der Schreibweise. Bei "new my_type" ist
der allokeirte Typ "Felder[5] von int". Felder, also, und damit
wird array new verwendet. Mit zwei Konsequenzen: der Typ des
Ergebnisses wird vom "T[]" in "T*" umgemappt, statt von "T" in
"T*", und man muss delete[] verwenden.

Ähnlicherwiese, mit "new int (&((*p)()))[ 10 ]" wird scalar new,
und nicht array new, aufgerufen. Der Typ des Ergebnisses ist
also "int (&((**)()))[ 10 ]", und nicht etwa "int (&((*)()))".
Und man muss danach delete, und nicht delete[], verwenden.

--
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

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Heinz Saathoff
Guest





PostPosted: Tue Feb 21, 2006 10:06 am    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote

Moin,

Quote:
Ähnlicherwiese, mit "new int (&((*p)()))[ 10 ]" wird scalar new,

Ich muss gestehen, dass ich diese new-expression nicht verstehe. Ist p
hier ein Typ oder eine Variable? Letzteres durfte in einer new-
expression doch gar nicht vorkommen? Dann der Operator '&', der entweder
als Adressoperator oder als Referenz interpretiert wird? Referenzen
lassen sich dorch gar nicht per new allokieren?

Quote:
und nicht array new, aufgerufen. Der Typ des Ergebnisses ist
also "int (&((**)()))[ 10 ]", und nicht etwa "int (&((*)()))".
^^^^^^^^^^^^^^^^^^^^^^

Ist das jetzt ein Zeiger auf einen Funktionzeiger, wo die Funktion eine
Referenz auf ein array mit 10 ints zurückgibt?

- Heinz

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
kanze
Guest





PostPosted: Tue Feb 21, 2006 11:06 am    Post subject: Re: Returntyp von Operator new und Arrays Reply with quote

Heinz Saathoff wrote:

Quote:
Ähnlicherwiese, mit "new int (&((*p)()))[ 10 ]" wird scalar new,

Ich muss gestehen, dass ich diese new-expression nicht verstehe.

Wobei du recht hast.

Quote:
Ist p hier ein Typ oder eine Variable?

Es ist eigentlich ein "Hilfer", das ich vergessen habe, zu
löschen. Bei komplizierten Typausdrücken wie diesem finde ich es
hilfreich, den Ausdruck zuerst zu formulieren, als ob ich eine
Variable definiere, und erst am Ende den Namen der Variable zu
löschen. In der Tat soll das p nicht da sein.

Quote:
Letzteres durfte in einer new- expression doch gar nicht
vorkommen? Dann der Operator '&', der entweder als
Adressoperator oder als Referenz interpretiert wird?
Referenzen lassen sich dorch gar nicht per new allokieren?

und nicht array new, aufgerufen. Der Typ des Ergebnisses ist
also "int (&((**)()))[ 10 ]", und nicht etwa "int (&((*)()))".
^^^^^^^^^^^^^^^^^^^^^^
Ist das jetzt ein Zeiger auf einen Funktionzeiger, wo die Funktion eine
Referenz auf ein array mit 10 ints zurückgibt?

Genau. Und der Ausdruck im new sollte auch so ähnlich aussehen,
ohne den p (mit aber einen * weniger).

Das Ziel war nur, ein Typ zu haben, dessen Name mit einem []
endet, obwohl er keine Feld ist. In der Tat denke ich, dass
solche Type selten vorkomment, und noch seltener dynamisch
allokiert werden. Ich wollte nur darauf hinweisen, dass man auf
die Schreibweise des Parameters von new nicht vertrauen kann;
man muss in allen Fällen zurück auf den richtigen Typ gehen.

--
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

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.