OVH Cloud OVH Cloud

initialiser un objet alloué (WAS: realloc et templates)

13 réponses
Avatar
Cyrille \cns\ Szymanski
Je cherchais à initialiser un objet ayant déjà été alloué.

Après une exploration de la STL Borland je suis tombé sur le code de
__construct

template <class T1, class T2>
inline void __construct (T1* p, const T2& value)
{
new (p) T1(value);
}

En utilisant directement ce code, on obtient une erreur indiquant que
'operator new(unsigned int,TestClass *)' n'existe pas.

int main()
{
TestClass *p = (TestClass*)malloc( sizeof(TestClass) );

__construct( p , 0 );

}

J'ai donc poussé plus loin la recherche dans la STL et je suis tombé sur
#define _RWSTDExportFunc(ReturnType) ReturnType
extern void _RWSTDExportFunc(*) operator new(size_t size, void* ptr);

Autrement dit
extern void * operator new(size_t size, void* ptr);


J'ai besoin d'un peu d'explications.


Merci d'avance,
--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/

10 réponses

1 2
Avatar
Cyrille \cns\ Szymanski
[...]

J'ai toujours trouvé regrettable la programmation orientée
copier/coller.


Sauf quand elle est à but pédagogique je suppose...


| En utilisant directement ce code, on obtient une erreur indiquant que
| 'operator new(unsigned int,TestClass *)' n'existe pas.

Il te manque certainement un

#include <new>


Effectivement cet opérateur est défni dans new.h

Pourquoi n'est-il pas défini par défaut comme new( size_t ) l'est ?

Pour plus d'info, consulte TC++PL3, §10.4.11 Placement of Objects.


Ok, il faut que je me trouve une référence sérieuse sur le c++. Mais à la
base j'étais pas parti pour approfondir ce langage.


--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/

Avatar
Fabien LE LEZ
On 19 Aug 2003 11:44:11 GMT, "Cyrille "cns" Szymanski"
wrote:

Ok, il faut que je me trouve une référence sérieuse sur le c++. Mais à la
base

j'étais pas parti pour approfondir ce langage.


Alors que tu cherches à aborder des notions plutôt complexes ? :-o


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Gabriel Dos Reis
--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable

"Cyrille "cns" Szymanski" writes:

| > [...]
| >
| > J'ai toujours trouvé regrettable la programmation orientée
| > copier/coller.
|
| Sauf quand elle est à but pédagogique je suppose...

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


je lui ai rarement trouvé des vertus pédagogiques.

--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable


| >| En utilisant directement ce code, on obtient une erreur indiquant que
| >| 'operator new(unsigned int,TestClass *)' n'existe pas.
| >
| > Il te manque certainement un
| >
| > #include <new>
|
| Effectivement cet opérateur est défni dans new.h

tu veux dire <new>, je suppose.

| Pourquoi n'est-il pas défini par défaut comme new( size_t ) l'est ?

Pardon ? Je n'ai pas compris la question.

-- Gaby

--=-=-=--
Avatar
Cyrille \cns\ Szymanski
| Pourquoi n'est-il pas défini par défaut comme new( size_t ) l'est ?

Pardon ? Je n'ai pas compris la question.


Hum... Je commence à me demander si j'ai pas mis les pieds dans le plat en
posant cette question. Au risque de faire criser les quelques talibans de
ce newsgroup je me lance.

Il me semble que void * operator new( size_t ) est défini de facto. Par
exemple le programme suivant compile (mais est-il valide ?).

int main() {
int *p = new int;
delete p;
return 0;
}

Alors que pour utiliser le new de position, il faut inclure <new> (en tout
cas sur mon implémentation, à savoir Borland C++ 5.5)

Ma question est, pourquoi ?

* Est-ce par chance que le programme ci-dessus compile et que pour qu'il
soit correct il faut inclure <new> parce qu'on se sert de new ?
* Est-ce pour des raisons historiques, et le fait que le placement new est
assez récent ?
* Est-ce parce que finalement l'usage du placement new est assez limité ?


--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/

Avatar
Fabien LE LEZ
On 19 Aug 2003 14:36:36 GMT, "Cyrille "cns" Szymanski"
wrote:

Est-ce parce que finalement l'usage du placement new est assez limité ?


Ça, c'est sûr -- même si je l'utilise (peut-être) en fait très souvent
via std::vector<>

--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Gabriel Dos Reis
--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable

"Cyrille "cns" Szymanski" writes:

| >| Pourquoi n'est-il pas défini par défaut comme new( size_t ) l'est ?
| >
| > Pardon ? Je n'ai pas compris la question.
|
| Hum... Je commence à me demander si j'ai pas mis les pieds dans le plat en
| posant cette question. Au risque de faire criser les quelques talibans de
| ce newsgroup je me lance.

les talibans en question te passent le bonjour.

| Il me semble que void * operator new( size_t ) est défini de facto. Par

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


Elle n'est pas définie de facto.

Elle est implicitement déclarée dans chaque unité de traduction et si
le programme n'en fournit pas une implémentation alors la définition
qui vient avec le compilateur/traducteur de programme est prise par
défaut. Mais chaque programme est libre de la remplacer.

| exemple le programme suivant compile (mais est-il valide ?).

Yep.

--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable


| int main() {
| int *p = new int;
| delete p;
| return 0;
| }
|
| Alors que pour utiliser le new de position, il faut inclure <new> (en tou t
| cas sur mon implémentation, à savoir Borland C++ 5.5)

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


Pour utiliser un new de placement, il faut déclarer une fonction new
correspondante. Si la déclaration standard te convient, tu inclus
<new>, sinon tu fournis ta propre déclaration/définition. Un peu comme
si la classe standard de chaîne de caractères te convient, tu inclus
<string> et tu utilises std::string, autrement tu définis ta propre
classe.

| Ma question est, pourquoi ?

la réponse est c'est comme ça :-)

| * Est-ce par chance que le programme ci-dessus compile et que pour qu'il
| soit correct il faut inclure <new> parce qu'on se sert de new ?

Le programme ci-dessus est correct. Si tu veux utiliser un new de
placement il te faut fournir une déclaration correspondante. Pour les
cas où on spécifie un pointeur pour désigner l'emplacement, il y a
une déclaration standard contenue dans <new>.

--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable


| * Est-ce pour des raisons historiques, et le fait que le placement new e st
| assez récent ?

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


Le new de placement est indéniablement venu après le new sans
fioriture. Le new de placement est venu dans la seconde fournée de C++
alors le new sans fioriture existait déjà en C with Classes.

Historiquement "new" sans fioriture était considérée essentielle en
C++, alors on exigeait pas d'inclure des entêtes juste pour dire new
-- et historiquement aussi, "new" voulait dire autre chose.

--=-=- Content-Type: text/plain; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable


| * Est-ce parce que finalement l'usage du placement new est assez limit é ?

--=-=- Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit


Je ne dirais pas que c'est limité. Cela peut être essentiel dans
certains projets, mais ce n'est d'utilisation aussi fréquente que le
new sans fioriture.
Je ne comprends pas pourquoi le fait de devoir inclure un en-tête
avant d'utiliser un truc avec fioriture devient subitement un
problème...

-- Gaby

--=-=-=--
Avatar
Christophe Lephay
"Gabriel Dos Reis" a écrit dans le message de
news:
"Cyrille "cns" Szymanski" writes:
| Ma question est, pourquoi ?

la réponse est c'est comme ça :-)


D'un autre coté, au vu de ce que tu as expliqué dans ce même post (et que
j'ai supprimé), celà semble logique de placer dans des entêtes les
fonctionnalités susceptibles de changer selon les desiderata du programmeur
:)

Chris

Avatar
Arnaud Meurgues
Christophe Lephay wrote:

D'un autre coté, au vu de ce que tu as expliqué dans ce même post (et que
j'ai supprimé), celà semble logique de placer dans des entêtes les
fonctionnalités susceptibles de changer selon les desiderata du programmeur
:)


Sauf que le new sans fioriture peut aussi être changé selon les
desiderata du programmeur et n'a pas besoin d'entête pour être utilisé...

Arnaud

Avatar
Gabriel Dos Reis
Arnaud Meurgues writes:

| Christophe Lephay wrote:
|
| > D'un autre coté, au vu de ce que tu as expliqué dans ce même post (et que
| > j'ai supprimé), celà semble logique de placer dans des entêtes les
| > fonctionnalités susceptibles de changer selon les desiderata du programmeur
| > :)
|
| Sauf que le new sans fioriture peut aussi être changé selon les
| desiderata du programmeur et n'a pas besoin d'entête pour être
| utilisé...

C'est plus subtile que ça : la déclaration de new sans fioriture ne
peut pas changer. Ce qui peut changer c'est sa définition -- dans ce
cas on dit que la fonction a été remplacée. Mais alors quelle serait
l'utilité de l'entête, si de toute façon la définition n'est pas
dans l'entête ?
Avatar
Cyrille \cns\ Szymanski
Je ne comprends pas pourquoi le fait de devoir inclure un en-tête
avant d'utiliser un truc avec fioriture devient subitement un
problème...


Aucun problème si on sait pourquoi ou a défaut, qu'on y est obligé.


--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/

1 2