Accueil > > > LE VECTEUR EST UN SACRÉ COPIEUR
LE VECTEUR EST UN SACRÉ COPIEUR
Information sur la source
Description
OK, le vecteur est beaucoup plus pratique que le tableau pour stocker les 'int' Mais que peut on lui confier à stocker ? avec quels avantages et inconvénients ? PARTIE I : le vecteur est vide, on lui ajoute un élément PARTIE II : le vecteur reçoit un deuxième élément PARTIE III : le vecteur reçoit un troisième élément PARTIE IV : l'insertion autre part qu'à la fin du tableau PARTIE V : Tentative d'optimisation de l'utilisation du vecteur PARTIE VI : Trop de copie ... on utilise des pointeurs... mais attention ! En conclusion : les bonnes pratiques et les interdits
Source
- //Le vecteur est un sacré copieur
- #include <iostream>
- #include <vector>
- using namespace std;
- /*On prendra une classe simple class A dotée d'un int pour "voir" comment les choses se passent */
- class A
- {
- private :
- int i_;
- public:
- A(int i=0) : i_(i){cout << "Ctor : " << i_ << endl;}
- // A(const A& a) : i_(a.i_){cout << "Ctor de copie : " << i_ << endl;} //a décommenter selon indication
- void print(ostream& out) const{ out << i_;}
- // ~A() {cout << "Dtor : " << i_ << endl;}
- };
- ostream& operator<<(ostream& out, const A& a) { a.print(out); return out;}
-
- int main()
- {
- //**********************************************************************
- //PARTIE I :le vecteur est vide, on lui ajoute un élément
- //**********************************************************************
- cout << "vector<A> v;" << endl;
- vector<A> v; //vecteur vide, destiné à stocker des objets A
-
- //ici, le vecteur est vide... la preuve :
- cout << "vecteur vide ? " << boolalpha << v.empty() << endl;
- A a1(1); //création d'un objet de type A
- cout << "v.push_back(a1);" << endl;
- v.push_back(a1);
- //ici, le vecteur n'est plus vide... la preuve :
- cout << "vecteur vide ? " << boolalpha << v.empty() << endl;
- //on peut accéder à sa capacité de stockage : combien d'éléments sont stockables sans nouvelle réallocation ?
- cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
- /*mais quel est l'objet qui a été stocké par le vector ?
- NON, la réponse a1 est FAUSSE ! Je vous avais prévenu (dans le titre de l'article)
- La bonne réponse est UNE COPIE DE a1 !
- Comment s'en apercevoir ? en traçant l'exécution du Ctor de copie => décommentez le
- On peut aussi chercher à écrire l'adresse mémoire du premier élément du vecteur : v[0]
- */
- cout << "@ de a1: &a1=" << &a1 << " et @ 1er element du vecteur &v[0]="<< &v[0] << endl;
- cout << "le vecteur lui-meme est en " << &v << " (pile)" << endl;
- /*on remarque ici que les adresses sont dans des plages différentes
- a1 est alloué sur la pile et l'objet copié dans le vecteur est alloué sur le tas...
- donc par de l'allocation dynamique...
- ce qui est nécessaire pour faire évoluer dynamiquement sa taille (augmentation ou diminution)
- */
- //**********************************************************************
- //PARTIE II : le vecteur reçoit un deuxième élément
- //**********************************************************************
- A a2(2); //création du deuxième objet de type A
- cout << "v.push_back(a2);" << endl;
- v.push_back(a2);
- /* Cette fois ci, la question est : qu'à fait le vecteur ?
- On sait qu'il a copié l'objet a2 est qu'il a ajouté la copie dans son conteneur
- mais allez voir la trace laissée par notre Ctor de copie !
- Pour mieux comprendre, allons voir l'adresse des deux éléments du vecteur
- */
- cout << " &v[0]="<< &v[0] << " et &v[1]="<< &v[1] << endl;
- cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
- //le conteneur (mémoire allouée) du vecteur se trouvait un peu à l'étroit à l'ancienne place,
- //il a donc déménagé dans un deux pièce... et copié chacun des éléments
- // Je vous avais prévenu ... blabla
-
- //**********************************************************************
- //PARTIE III : le vecteur reçoit un troisième élément
- //**********************************************************************
- A a3(3);
- cout << "v.push_back(a3);" << endl;
- v.push_back(a3);
- /* Cette fois ci, la question est qu'à fait le vecteur ?
- On sait maintenant qu'il a alloué suffisamment de place pour stocker les 3 éléments
- Mais il a anticipé les allocations futures et optimisé en allouant 4 objets... la preuve
- */
- cout << " &v[0]="<< &v[0] << ", &v[1]="<< &v[1] << " et &v[2]="<< &v[2] << endl;
- cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
- /* Remarquons que ce comportement du vecteur n'est pas spécifié par les standards et que chaque
- implémentation peut se comporter différemment : le vecteur de l'implémentation VC++ alloue le double de la taille courante
- lors de chaque nouveau besoin
- Pour vérifier cela, que les éléments ne sont pas copiés cette fois ci, ajoutons un autre élément
- */
- cout << "v.push_back(a4);" << endl;
- v.push_back(A(4));
- cout << " &v[0]="<< &v[0] << ", &v[1]="<< &v[1] << ", &v[2]="<< &v[2] << " et &v[3]="<< &v[3] << endl;
- cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
- //on retire alors cet élément
- cout << "pop_back de : " << v.back()<< " par v.pop_back();" << endl;
- v.pop_back();
- //remarque 1 : l'appel à pop_back() appelle le destructeur de l'objet chassé
- //remarque 2 : le pop_back ne renvoie rien, il convient d'avoir récupéré l'objet par back() si besoin est
- cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
- /*
- Pourquoi ces réallocations ?
- Car le vecteur est implémenté par un tableau en memoire dynamique ... et tous les éléments d'un tableau sont contigus
- C'est d'ailleurs ce qui rend le tableau si efficace lors de l'accès aléatoire par l'opérateur []
- L'élément 2 est alors récupéré directement par son adresse : adresse_début_tableau+2*sizeof(élément)
-
- **********************************************************************
- PARTIE IV : l'insertion autre part qu'à la fin du tableau
- **********************************************************************
- Il existe la possibilité d'insérer des éléments à la position de notre choix dans le tableau
- La méthode 'insert' permet cela, à condition de lui fournir un itérateur initialisé sur l'élément
- devant lequel on veut insérer notre nouvel élément.
- Par exemple, pour initialiser un itérateur au début du vecteur :
- */
- vector<A>::iterator it = v.begin();
- // Pour insérer un objet a4 :
- A a4(4);
- cout << "v.insert(v.begin(), a4);" << endl;
- v.insert(v.begin(), a4);//ou à des emplacements différents : v.insert(v.begin()+1, a4);
- //v.insert(it, a4);
- cout << " &v[0]="<< &v[0] << ", &v[1]="<< &v[1] << ", &v[2]="<< &v[2] << ", &v[3]="<< &v[3] << " et &v[4]="<< &v[4] << endl;
- /* Que fait le vecteur à votre avis ?
- Comment ? il copie tout le monde ? tous les éléments suivant le point d'insertion ?
- et ceci, même s'il a suffisamment de place dans sa capacité ?
- PAS DU TOUT ! sur ce coup là, il optimise les appels au ctor de copie dans les déplacements mémoire
- C'est pour montrer ceci que nous avons retiré l'ancien 4ème élément dans la partie précédente.
- Mais au fait, comment les éléments sont ils déplacés ?
- Comme nos Ctors de copies ne sont pas appelés, la copie est faite par bit-copy
- */
- //ici des exemples de parcours du vecteur fonctionnellement identiques
- for (it=v.begin(); it!=v.end(); it++)//boucle avec itérateur
- cout << *it << " "; //impression de l?élément via l'itérateur (déréférencé)
- cout << endl;
- for (int i =0; i<v.size(); i++)//boucle simple
- cout << v[i] << " "; //impression de l?élément via l'opérateur []
- cout << endl;
- //ici une faible utilisation du vecteur, le parcours direct par un pointeur utilisateur
- A * ptr = &v[0];
- for (int ii=0; ii<4; ii++)
- cout << *ptr++ << " " ;
- cout << endl;
-
- /*********************************************************************
- PARTIE V : Tentative d'optimisation de l'utilisation du vecteur
- **********************************************************************
- Que de copies d'objet lorsque les insertions sont faites une par une !
- Dans le cas de figure ou nous savons à peu près combien d'objets seront mis dans le vecteur,
- l'idée est de TAILLER notre vecteur dès le début.
- Pour faire cela, tournons nous vers les Constructeurs du vecteur, nous en voyons un qui SEMBLE
- répondre à notre souhait
- explicit vector(size_type n, const T& v = T(), const A& al = A());
- Utilisons le pour vérifier son fonctionnement
- */
- cout << "vector<A> v2(5);" << endl;
- vector<A> v2(5);
- /*Qu'a t il fait ?
- BRAVO : il a copié ! il a d'abord utilisé le Ctor par défaut de A pour créer un objet temporaire
- il a ensuite utilisé cet objet temporaire comme source d'information pour la création par le Ctor de copie
- des autres éléments (les vrais) v2[0], .... v2[4] et il a ensuite détruit l'objet temporaire.
- On voit aussi que l'on peut choisir l'objet source de copie en codant ainsi :
- */
- cout << "vector<A> v3(5, A(10));\n";
- vector<A> v3(5, A(10));
- /*
- Quand un vecteur est trop petit, peux t on suggérer nous même l'aggrandissement ?
- OUI en utilisant la méthode resize()
- */
- cout << "avant resize : capacity=" << v3.capacity() << " et size=" << v3.size() << endl;
- cout << "v3.resize(20);\n";
- v3.resize(20);
- cout << "apres resize : capacity=" << v3.capacity() << " et size=" << v3.size() << endl;
- /*
- On a pas mal de copies, mais par rapport à la construction d'un vecteur vide suivi de push_back
- on gagne les réallocations mémoire et copies intermédiaires successives
- Mais n'y a t il pas un moyen de tailler le vecteur SANS CREER TOUS CES OBJETS ?
- La réponse est dans la méthode reserve()
- */
- vector<A> v4;
- cout << "\nv4.reserve(20); \n";
- v4.reserve(20);
- cout << "apres reserve : capacity=" << v4.capacity() << " et size=" << v4.size() << endl;
- //reserve est différent de resize dans la mesure ou il ne s'occupe que de la mémoire allouée
- //et PAS des objets du vecteur : pas de création et donc pas de copie
-
- /*************************************************************************
- PARTIE VI : Trop de copie ... on utilise des pointeurs... mais attention !
- **************************************************************************
- Que de copies d'objet ! l'idée suivante est de ne confier au conteneur que des pointeurs
- sur mes objets
- On va donc créer un objet dynamiquement et l'ajouter au vecteur
- */
-
- {
- A* pa=new A(1);
- vector<A*> v5;
- v5.push_back((A*)&v5);
- v5.resize(2);//cette fois ci, le resize ne fait pas de copie d'objet
- cout << "cap=" <<v5.capacity() << " et size=" << v5.size() << endl;
- //ici, une boucle jusqu'a size-1 provoquerait un TRAP
- for (int i =0; i<v5.size(); i++)//boucle simple
- // cout << *v5[i] << " "; //A décommenter pour voir le trap
- cout << endl;
- //ici, lorsque le vecteur va être détruit, ne pas oublier de libérer l'objet par
- delete pa; // car le destructeur de vector ne fera rien pour nos pointeurs
- }
- return 0;
- }
- /*
- En conclusion :
- La bonne pratique est d'anticiper la taille finale de l'objet vecteur dès sa construction
- ou au moins par une opération de reserve faite avant la première insertion.
- Ceci n'est pas toujours possible ... évidemment
-
- Les interdits :
- - si vous avez un objet lent à copier ou un objet non copiable (Ctor de copie privé)
- il est impossible d'utiliser le vecteur
- - De même, si votre objet ne possède pas de Ctor par défaut, l'utilisation du vecteur est handicappée
- car les resize y font appel
- - Pour éviter toutes les copies lourdes, on pourrait envisager de confier des pointeurs à notre vecteur
- Mais alors il faut gérer nous même la synchronisation du conteneur, des pointeurs et des objets
- En particulier, la création par new d'un objet et l'ajout du pointeur dans le vecteur nécessitera
- l'appel à delete lors de la destruction du vecteur... car le vecteur appellera seulement le destructeur
- de ce que nous lui avons confié... un pointeur. Le type pointeur n'étant pas une classe, aucun destructeur
- n'est appelé automatiquement.
- */
//Le vecteur est un sacré copieur
#include <iostream>
#include <vector>
using namespace std;
/*On prendra une classe simple class A dotée d'un int pour "voir" comment les choses se passent */
class A
{
private :
int i_;
public:
A(int i=0) : i_(i){cout << "Ctor : " << i_ << endl;}
// A(const A& a) : i_(a.i_){cout << "Ctor de copie : " << i_ << endl;} //a décommenter selon indication
void print(ostream& out) const{ out << i_;}
// ~A() {cout << "Dtor : " << i_ << endl;}
};
ostream& operator<<(ostream& out, const A& a) { a.print(out); return out;}
int main()
{
//**********************************************************************
//PARTIE I :le vecteur est vide, on lui ajoute un élément
//**********************************************************************
cout << "vector<A> v;" << endl;
vector<A> v; //vecteur vide, destiné à stocker des objets A
//ici, le vecteur est vide... la preuve :
cout << "vecteur vide ? " << boolalpha << v.empty() << endl;
A a1(1); //création d'un objet de type A
cout << "v.push_back(a1);" << endl;
v.push_back(a1);
//ici, le vecteur n'est plus vide... la preuve :
cout << "vecteur vide ? " << boolalpha << v.empty() << endl;
//on peut accéder à sa capacité de stockage : combien d'éléments sont stockables sans nouvelle réallocation ?
cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
/*mais quel est l'objet qui a été stocké par le vector ?
NON, la réponse a1 est FAUSSE ! Je vous avais prévenu (dans le titre de l'article)
La bonne réponse est UNE COPIE DE a1 !
Comment s'en apercevoir ? en traçant l'exécution du Ctor de copie => décommentez le
On peut aussi chercher à écrire l'adresse mémoire du premier élément du vecteur : v[0]
*/
cout << "@ de a1: &a1=" << &a1 << " et @ 1er element du vecteur &v[0]="<< &v[0] << endl;
cout << "le vecteur lui-meme est en " << &v << " (pile)" << endl;
/*on remarque ici que les adresses sont dans des plages différentes
a1 est alloué sur la pile et l'objet copié dans le vecteur est alloué sur le tas...
donc par de l'allocation dynamique...
ce qui est nécessaire pour faire évoluer dynamiquement sa taille (augmentation ou diminution)
*/
//**********************************************************************
//PARTIE II : le vecteur reçoit un deuxième élément
//**********************************************************************
A a2(2); //création du deuxième objet de type A
cout << "v.push_back(a2);" << endl;
v.push_back(a2);
/* Cette fois ci, la question est : qu'à fait le vecteur ?
On sait qu'il a copié l'objet a2 est qu'il a ajouté la copie dans son conteneur
mais allez voir la trace laissée par notre Ctor de copie !
Pour mieux comprendre, allons voir l'adresse des deux éléments du vecteur
*/
cout << " &v[0]="<< &v[0] << " et &v[1]="<< &v[1] << endl;
cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
//le conteneur (mémoire allouée) du vecteur se trouvait un peu à l'étroit à l'ancienne place,
//il a donc déménagé dans un deux pièce... et copié chacun des éléments
// Je vous avais prévenu ... blabla
//**********************************************************************
//PARTIE III : le vecteur reçoit un troisième élément
//**********************************************************************
A a3(3);
cout << "v.push_back(a3);" << endl;
v.push_back(a3);
/* Cette fois ci, la question est qu'à fait le vecteur ?
On sait maintenant qu'il a alloué suffisamment de place pour stocker les 3 éléments
Mais il a anticipé les allocations futures et optimisé en allouant 4 objets... la preuve
*/
cout << " &v[0]="<< &v[0] << ", &v[1]="<< &v[1] << " et &v[2]="<< &v[2] << endl;
cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
/* Remarquons que ce comportement du vecteur n'est pas spécifié par les standards et que chaque
implémentation peut se comporter différemment : le vecteur de l'implémentation VC++ alloue le double de la taille courante
lors de chaque nouveau besoin
Pour vérifier cela, que les éléments ne sont pas copiés cette fois ci, ajoutons un autre élément
*/
cout << "v.push_back(a4);" << endl;
v.push_back(A(4));
cout << " &v[0]="<< &v[0] << ", &v[1]="<< &v[1] << ", &v[2]="<< &v[2] << " et &v[3]="<< &v[3] << endl;
cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
//on retire alors cet élément
cout << "pop_back de : " << v.back()<< " par v.pop_back();" << endl;
v.pop_back();
//remarque 1 : l'appel à pop_back() appelle le destructeur de l'objet chassé
//remarque 2 : le pop_back ne renvoie rien, il convient d'avoir récupéré l'objet par back() si besoin est
cout << "capacite du vecteur = " << v.capacity() << ", taille = " << v.size() << endl;
/*
Pourquoi ces réallocations ?
Car le vecteur est implémenté par un tableau en memoire dynamique ... et tous les éléments d'un tableau sont contigus
C'est d'ailleurs ce qui rend le tableau si efficace lors de l'accès aléatoire par l'opérateur []
L'élément 2 est alors récupéré directement par son adresse : adresse_début_tableau+2*sizeof(élément)
**********************************************************************
PARTIE IV : l'insertion autre part qu'à la fin du tableau
**********************************************************************
Il existe la possibilité d'insérer des éléments à la position de notre choix dans le tableau
La méthode 'insert' permet cela, à condition de lui fournir un itérateur initialisé sur l'élément
devant lequel on veut insérer notre nouvel élément.
Par exemple, pour initialiser un itérateur au début du vecteur :
*/
vector<A>::iterator it = v.begin();
// Pour insérer un objet a4 :
A a4(4);
cout << "v.insert(v.begin(), a4);" << endl;
v.insert(v.begin(), a4);//ou à des emplacements différents : v.insert(v.begin()+1, a4);
//v.insert(it, a4);
cout << " &v[0]="<< &v[0] << ", &v[1]="<< &v[1] << ", &v[2]="<< &v[2] << ", &v[3]="<< &v[3] << " et &v[4]="<< &v[4] << endl;
/* Que fait le vecteur à votre avis ?
Comment ? il copie tout le monde ? tous les éléments suivant le point d'insertion ?
et ceci, même s'il a suffisamment de place dans sa capacité ?
PAS DU TOUT ! sur ce coup là, il optimise les appels au ctor de copie dans les déplacements mémoire
C'est pour montrer ceci que nous avons retiré l'ancien 4ème élément dans la partie précédente.
Mais au fait, comment les éléments sont ils déplacés ?
Comme nos Ctors de copies ne sont pas appelés, la copie est faite par bit-copy
*/
//ici des exemples de parcours du vecteur fonctionnellement identiques
for (it=v.begin(); it!=v.end(); it++)//boucle avec itérateur
cout << *it << " "; //impression de l?élément via l'itérateur (déréférencé)
cout << endl;
for (int i =0; i<v.size(); i++)//boucle simple
cout << v[i] << " "; //impression de l?élément via l'opérateur []
cout << endl;
//ici une faible utilisation du vecteur, le parcours direct par un pointeur utilisateur
A * ptr = &v[0];
for (int ii=0; ii<4; ii++)
cout << *ptr++ << " " ;
cout << endl;
/*********************************************************************
PARTIE V : Tentative d'optimisation de l'utilisation du vecteur
**********************************************************************
Que de copies d'objet lorsque les insertions sont faites une par une !
Dans le cas de figure ou nous savons à peu près combien d'objets seront mis dans le vecteur,
l'idée est de TAILLER notre vecteur dès le début.
Pour faire cela, tournons nous vers les Constructeurs du vecteur, nous en voyons un qui SEMBLE
répondre à notre souhait
explicit vector(size_type n, const T& v = T(), const A& al = A());
Utilisons le pour vérifier son fonctionnement
*/
cout << "vector<A> v2(5);" << endl;
vector<A> v2(5);
/*Qu'a t il fait ?
BRAVO : il a copié ! il a d'abord utilisé le Ctor par défaut de A pour créer un objet temporaire
il a ensuite utilisé cet objet temporaire comme source d'information pour la création par le Ctor de copie
des autres éléments (les vrais) v2[0], .... v2[4] et il a ensuite détruit l'objet temporaire.
On voit aussi que l'on peut choisir l'objet source de copie en codant ainsi :
*/
cout << "vector<A> v3(5, A(10));\n";
vector<A> v3(5, A(10));
/*
Quand un vecteur est trop petit, peux t on suggérer nous même l'aggrandissement ?
OUI en utilisant la méthode resize()
*/
cout << "avant resize : capacity=" << v3.capacity() << " et size=" << v3.size() << endl;
cout << "v3.resize(20);\n";
v3.resize(20);
cout << "apres resize : capacity=" << v3.capacity() << " et size=" << v3.size() << endl;
/*
On a pas mal de copies, mais par rapport à la construction d'un vecteur vide suivi de push_back
on gagne les réallocations mémoire et copies intermédiaires successives
Mais n'y a t il pas un moyen de tailler le vecteur SANS CREER TOUS CES OBJETS ?
La réponse est dans la méthode reserve()
*/
vector<A> v4;
cout << "\nv4.reserve(20); \n";
v4.reserve(20);
cout << "apres reserve : capacity=" << v4.capacity() << " et size=" << v4.size() << endl;
//reserve est différent de resize dans la mesure ou il ne s'occupe que de la mémoire allouée
//et PAS des objets du vecteur : pas de création et donc pas de copie
/*************************************************************************
PARTIE VI : Trop de copie ... on utilise des pointeurs... mais attention !
**************************************************************************
Que de copies d'objet ! l'idée suivante est de ne confier au conteneur que des pointeurs
sur mes objets
On va donc créer un objet dynamiquement et l'ajouter au vecteur
*/
{
A* pa=new A(1);
vector<A*> v5;
v5.push_back((A*)&v5);
v5.resize(2);//cette fois ci, le resize ne fait pas de copie d'objet
cout << "cap=" <<v5.capacity() << " et size=" << v5.size() << endl;
//ici, une boucle jusqu'a size-1 provoquerait un TRAP
for (int i =0; i<v5.size(); i++)//boucle simple
// cout << *v5[i] << " "; //A décommenter pour voir le trap
cout << endl;
//ici, lorsque le vecteur va être détruit, ne pas oublier de libérer l'objet par
delete pa; // car le destructeur de vector ne fera rien pour nos pointeurs
}
return 0;
}
/*
En conclusion :
La bonne pratique est d'anticiper la taille finale de l'objet vecteur dès sa construction
ou au moins par une opération de reserve faite avant la première insertion.
Ceci n'est pas toujours possible ... évidemment
Les interdits :
- si vous avez un objet lent à copier ou un objet non copiable (Ctor de copie privé)
il est impossible d'utiliser le vecteur
- De même, si votre objet ne possède pas de Ctor par défaut, l'utilisation du vecteur est handicappée
car les resize y font appel
- Pour éviter toutes les copies lourdes, on pourrait envisager de confier des pointeurs à notre vecteur
Mais alors il faut gérer nous même la synchronisation du conteneur, des pointeurs et des objets
En particulier, la création par new d'un objet et l'ajout du pointeur dans le vecteur nécessitera
l'appel à delete lors de la destruction du vecteur... car le vecteur appellera seulement le destructeur
de ce que nous lui avons confié... un pointeur. Le type pointeur n'étant pas une classe, aucun destructeur
n'est appelé automatiquement.
*/
Sources du même auteur
Sources de la même categorie
Commentaires et avis
|
Derniers Blogs
[WINDOWSPHONE7] LECTEUR DE FLUX RSS[WINDOWSPHONE7] LECTEUR DE FLUX RSS par Vko
Parce que j'aime pas tester à moitié, je me suis amusé à développer un petit lecteur de flux RSS avec un look qui vous rappellera surement quelque chose :) La RC de Visual Studio est plutôt molle mais fonctionne correctement. L'émulateur est pas...
Cliquez pour lire la suite de l'article par Vko [WP7] L'éMULATEUR WINDOWS PHONE 7 EST MULTITâCHE[WP7] L'éMULATEUR WINDOWS PHONE 7 EST MULTITâCHE par KooKiz
Une question qui reste en suspend concernant Windows Phone 7 est de savoir si le système permettra à plusieurs applications de s'exécuter simultanément, ou si un système de mise en pause similaire à celui de l'iPhone sera adopté. Même si cela ne perm...
Cliquez pour lire la suite de l'article par KooKiz PRéSENTATION CLUB MOSS CE JOUR "LA NOUVELLE ARCHITECTURE DE SERVICES SHAREPOINT 2010".PRéSENTATION CLUB MOSS CE JOUR "LA NOUVELLE ARCHITECTURE DE SERVICES SHAREPOINT 2010". par Patrick Guimonet
Ca y est la sortie RTM de SharePoint 2010 est annoncée pour le 16 avril 2010 (annonce faite ce jour par Erol Giraudy lors de la réunion du club MOSS). Vous pourrez trouver ici les slides de ma présentation du jour dans le cadre du club MOSS : 201...
Cliquez pour lire la suite de l'article par Patrick Guimonet [WINDOWPHONE7] PREMIERS PAS[WINDOWPHONE7] PREMIERS PAS par Vko
Hop voici les premiers pas avec les outils de développement pour Windows Phone 7. Premier changement suite à l'installation des outils : les type de projets pour la plateforme Windows Phone 7. Les projets se découpent en deux groupes : Les projet...
Cliquez pour lire la suite de l'article par Vko [WP7] LE SDK DE WINDOWS PHONE 7 EST DISPONIBLE ![WP7] LE SDK DE WINDOWS PHONE 7 EST DISPONIBLE ! par KooKiz
Comme le titre l'indique, une première CTP du kit de développement pour Windows Phone 7 est disponible. Basé sur Visual Studio 2010 Express, il propose de développer des applications pour WP7 en Silverlight ou XNA 4. Un émulateur est bien entendu de l...
Cliquez pour lire la suite de l'article par KooKiz
Logiciels
Xilisoft Convertisseur Vidéo Ultimate (5.1.39.0305)XILISOFT CONVERTISSEUR VIDéO ULTIMATE (5.1.39.0305)Xilisoft Convertisseur Vidéo Ultimate est un outil puissant de conversion vidéo, facile à utilise... Cliquez pour télécharger Xilisoft Convertisseur Vidéo Ultimate Xilisoft DVD Ripper Ultimate (5.0.64.0304)XILISOFT DVD RIPPER ULTIMATE (5.0.64.0304)Xilisoft DVD Ripper Ultimate est un logiciel excellent pour copier et convertir DVD vers presque ... Cliquez pour télécharger Xilisoft DVD Ripper Ultimate Rigs of Rods (63.3)RIGS OF RODS (63.3)c'est un jeu de multi-simulation camions,autobus voitures, avions, bateaux, hélicoptère avec défo... Cliquez pour télécharger Rigs of Rods Konvertor (4.00)KONVERTOR (4.00)Le logiciel est un gestionnaire multimedia affichant, jouant et convertissant plus de 2000 format... Cliquez pour télécharger Konvertor
|