OVH Cloud OVH Cloud

[debutant] vector

15 réponses
Avatar
Bruno CAUSSE
Apres avoir lu les contributions de la liste je "passe" aux vectors :-)

J'ai une,

class A {

int a;
int b;
Int c;

A(): a(0), b(0), c(0) {}
};

class B {

/* pointeur pour pouvoir intervertir premier et deuxieme rapidement c.a.d.
Sans recopie d'objet; */

A* premier;
A* deuxieme;

B() : premier(NULL), deuxieme(NULL) {

Try {
Premier = new A();
Deuxieme = new A();
} catch (std::bad_alloc& e_bd) {
delete A;
throw;
}
}

~B() {
delete A;
delete B;
}

};

class C {

std::vector<B> table;

C(int n_elts) {
/* initialise la taille du vecteur et INITIALISE CHAQUE ELT par appel au
constructeur B(); */
table.resize(n_elts);
}

}

Est ce correcte?

Si la creation d'un objet C echoue (capacité trop grande) que se passe t'il?
Comment en etre informé, les objets B alloués sont t'ils detruits?

Peut on fixer ("const") la taille d'un vecteur. Aucun retrait ou ajout?

Merci
--
bruno

5 réponses

1 2
Avatar
Bruno CAUSSE
dans l'article , Fabien LE LEZ à
a écrit le 12/08/05 11:52 :

On Fri, 12 Aug 2005 11:15:50 +0200, Bruno CAUSSE :

En passant, si cette adresse n'est pas correcte, merci de rajouter
".invalid" à la fin.


Je le note.

/* pointeur pour pouvoir intervertir premier et deuxieme rapidement c.a.d.
Sans recopie d'objet; */

A* premier;
A* deuxieme;


C'est un peu une bombe nucléaire pour tuer une mouche.
Tu fais là de l'optimisation précoce : tu compliques le code dans
l'espoir que ton programme aille plus vite, mais sans savoir à
l'avance s'il y a réellement un problème de vitesse.
Si ça se trouve, tes bidouillages ralentiront le programme.



Evidement A n'est pas si simple. Et je peux en intervertir + de 100 000 par
seconde.

Donc, ton code me paraît incorrect pour deux raisons :

- comme il y a des pointeurs et de l'allocation dynamique, tu dois
rajouter un construteur de copie et un opérateur de copie -- en
l'état, ça plantera à la première copie.


Oui,

- ton code est inutilement compliqué, et je considère ça comme une
erreur de programmation.

Peut on fixer ("const") la taille d'un vecteur. Aucun retrait ou ajout?


J'ai du mal à comprendre ta terminologie. Parles-tu ici d'un tableau
(std::vector<>),


Oui, desolé

ou d'un vecteur, i.e. objet mathématique, élément
d'un espace vectoriel, représenté généralement par un tableau de
taille fixe ?


non, donc

Si tu veux un tableau de taille fixe connue à la compilation, un
tableau "à la C" convient :
static size_t const taille_tableau= 42;
int tableau [taille_tableau];


Justement je passe aux vector (1ere ligne de mon 1er post);-)


Si tu veux un tableau de taille fixée dans le constructeur, ce n'est
pas très difficile à programmer :

template <class T> class TableauTailleFixe
{
public:
typedef std::vector<T> Data;
typedef Data::iterator iterator;
typedef Data::const_iterator const_iterator;

TableauTailleFixe (size_t taille, T const& t= T())
: data (taille, t) {}

T& operator[] (size_t n) { return data.at(n); }
T const& operator[] (size_t n) const { return data.at(n); }

const_iterator begin() const { return data.begin(); }
const_iterator end() const { return data.end(); }
iterator begin() { return data.begin(); }
iterator end() { return data.end(); }

private:
Data data;
};

Note : il manque quelques trucs, comme les reverse_iterator, mais tu
peux les rajouter au fur et à mesure de tes besoins.




Avatar
Fabien LE LEZ
On Fri, 12 Aug 2005 11:59:48 +0200, Bruno CAUSSE :

Evidement A n'est pas si simple. Et je peux en intervertir + de 100 000 par
seconde.


Ça ne change rien à mon raisonnement.

Est-ce que que A est copiable ?
Si oui, il faut utiliser la méthode la plus simple : B contient deux
objets de classe A.
Si à l'exécution on se rend compte que c'est trop lent, et si le
profiler indique que c'est à cause de ça, alors on peut utiliser une
autre méthode. A priori, le deuxième essai sera avec
boost::shared_ptr.

Si tu veux un tableau de taille fixe connue à la compilation, un
tableau "à la C" convient :
static size_t const taille_tableau= 42;
int tableau [taille_tableau];


Justement je passe aux vector (1ere ligne de mon 1er post)


On ne "passe" pas aux std::vector<>. Ce n'est pas une religion. On
utilise std::vector<> quand c'est cette méthode qui convient, et on
utilise une autre méthode sinon.


Avatar
Arnaud Meurgues
Bruno CAUSSE wrote:

B(const B& src) {

//cas particulier que des membres primitifs (int)
*premier = *(src.premier);
*deuxieme = *(src.deuxieme);
};


Heu...
À quel moment *premier est-il créé ?

--
Arnaud

Avatar
Bruno CAUSSE
dans l'article , Jean-Marc Bourguet à
a écrit le 12/08/05 11:53 :

1/ quel est la difference entre
*this != src
et
this != &src


Encore un fois un peu trop vite

*this != src -> compare le contenu? (est ce valide sur A?)

Donc this != &src compare les adresses.

2/ Pourquoi est-ce que le test
*this != src
est necessaire? (En premiere approximation, si un tel test est
necessaire, il y a grande chance que le code soit incorrect en
presence d'exceptions)


Explication svp.

Avatar
Jean-Marc Bourguet
Bruno CAUSSE writes:

dans l'article , Jean-Marc Bourguet à
a écrit le 12/08/05 11:53 :

1/ quel est la difference entre
*this != src
et
this != &src


Encore un fois un peu trop vite

*this != src -> compare le contenu? (est ce valide sur A?)


Les operateurs de comparaisons ne sont pas generes automatiquement par
le compilateur. Donc il n'y en a ni pour A ni pour B...


Donc this != &src compare les adresses.

2/ Pourquoi est-ce que le test
*this != src
est necessaire? (En premiere approximation, si un tel test est
necessaire, il y a grande chance que le code soit incorrect en
presence d'exceptions)


Explication svp.


Si j'ai bonne memoire, ce doit se trouver ici

http://www.gotw.ca/gotw/023.htm

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org


1 2