je réalise en ce moment un petit soft de montage vidéo, et je voulais
savoir ce que vous pensiezdes classes suivantes, représentant les
différents objets pouvant être insérés dans 1 projet:
//La classe de base
class Montage_Sequence
{
public:
mutable AnsiString nom_sequence;
mutable long index_ds_timeline; //Position dans le projet
mutable Time_Period temps; //Temps de la séquence
int left; //Coordonnées de la vignette dans le projet
int top;
_type_sequence type_sequence;
//Images
class Montage_Image : public Montage_Sequence, public Montage_Track,
public Montage_Preview
{
public:
__fastcall Montage_Image()
: Montage_Sequence(ms_Image) {}
};
//Titres
class Montage_Titre : public Montage_Sequence, public Montage_Preview
{
public:
AnsiString texte;
TColor background;
TColor foreground;
//Transitions
class Montage_Transition : public Montage_Sequence
{
public:
__fastcall Montage_Transition()
: Montage_Sequence(ms_Transition) {}
};
Qu'est-ce que vous pensez de cette organisation?
Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes
virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en
tant que telles?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Olivier Azeau
Michael wrote:
Bonjour à tous,
je réalise en ce moment un petit soft de montage vidéo, et je voulais savoir ce que vous pensiezdes classes suivantes, représentant les différents objets pouvant être insérés dans 1 projet:
const enum _type_sequence { ms_Video, ms_Image, ms_Titre, ms_Transition }; Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
//La classe de base class Montage_Sequence { public: mutable AnsiString nom_sequence; mutable long index_ds_timeline; //Position dans le projet mutable Time_Period temps; //Temps de la séquence int left; //Coordonnées de la vignette dans le projet int top; Probablement un peu trop de trucs publics par ici qui vont induire un
couplage fort avec les utilisations de cette classe.
_type_sequence type_sequence; j'imagine que type de sequence n'a pas de raison d'être modifié après la
création de l'objet ? Un méthode virtuelle pure ne serait-elle pas une meilleure solution ?
//Images class Montage_Image : public Montage_Sequence, public Montage_Track, public Montage_Preview { public: __fastcall Montage_Image() : Montage_Sequence(ms_Image) {} };
//Titres class Montage_Titre : public Montage_Sequence, public Montage_Preview { public: AnsiString texte; TColor background; TColor foreground;
//Transitions class Montage_Transition : public Montage_Sequence { public: __fastcall Montage_Transition() : Montage_Sequence(ms_Transition) {} };
Qu'est-ce que vous pensez de cette organisation? Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de Montage_Track ou Montage_Preview, alors un destructeur protected et un héritage privé devraient suffire.
La question importante est de savoir si ces 2 classes ne réprésentent que des implémentations (path vers un fichier de stockage, image de previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi un comportement (capacité à se stocker physiquement accèdée par un gestionnaire de media, capacité de visualisation accèdée par une fenêtre de timeline, ...) auquel cas il serait peut être plus utile d'exposer des interfaces plutôt que des membres d'implémentation.
Michael wrote:
Bonjour à tous,
je réalise en ce moment un petit soft de montage vidéo, et je voulais
savoir ce que vous pensiezdes classes suivantes, représentant les
différents objets pouvant être insérés dans 1 projet:
const enum _type_sequence { ms_Video, ms_Image, ms_Titre, ms_Transition
};
Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
//La classe de base
class Montage_Sequence
{
public:
mutable AnsiString nom_sequence;
mutable long index_ds_timeline; //Position dans le projet
mutable Time_Period temps; //Temps de la séquence
int left; //Coordonnées de la vignette dans le projet
int top;
Probablement un peu trop de trucs publics par ici qui vont induire un
couplage fort avec les utilisations de cette classe.
_type_sequence type_sequence;
j'imagine que type de sequence n'a pas de raison d'être modifié après la
création de l'objet ?
Un méthode virtuelle pure ne serait-elle pas une meilleure solution ?
//Images
class Montage_Image : public Montage_Sequence, public Montage_Track,
public Montage_Preview
{
public:
__fastcall Montage_Image()
: Montage_Sequence(ms_Image) {}
};
//Titres
class Montage_Titre : public Montage_Sequence, public Montage_Preview
{
public:
AnsiString texte;
TColor background;
TColor foreground;
//Transitions
class Montage_Transition : public Montage_Sequence
{
public:
__fastcall Montage_Transition()
: Montage_Sequence(ms_Transition) {}
};
Qu'est-ce que vous pensez de cette organisation?
Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes
virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en
tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de
Montage_Track ou Montage_Preview, alors un destructeur protected et un
héritage privé devraient suffire.
La question importante est de savoir si ces 2 classes ne réprésentent
que des implémentations (path vers un fichier de stockage, image de
previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi
un comportement (capacité à se stocker physiquement accèdée par un
gestionnaire de media, capacité de visualisation accèdée par une fenêtre
de timeline, ...) auquel cas il serait peut être plus utile d'exposer
des interfaces plutôt que des membres d'implémentation.
je réalise en ce moment un petit soft de montage vidéo, et je voulais savoir ce que vous pensiezdes classes suivantes, représentant les différents objets pouvant être insérés dans 1 projet:
const enum _type_sequence { ms_Video, ms_Image, ms_Titre, ms_Transition }; Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
//La classe de base class Montage_Sequence { public: mutable AnsiString nom_sequence; mutable long index_ds_timeline; //Position dans le projet mutable Time_Period temps; //Temps de la séquence int left; //Coordonnées de la vignette dans le projet int top; Probablement un peu trop de trucs publics par ici qui vont induire un
couplage fort avec les utilisations de cette classe.
_type_sequence type_sequence; j'imagine que type de sequence n'a pas de raison d'être modifié après la
création de l'objet ? Un méthode virtuelle pure ne serait-elle pas une meilleure solution ?
//Images class Montage_Image : public Montage_Sequence, public Montage_Track, public Montage_Preview { public: __fastcall Montage_Image() : Montage_Sequence(ms_Image) {} };
//Titres class Montage_Titre : public Montage_Sequence, public Montage_Preview { public: AnsiString texte; TColor background; TColor foreground;
//Transitions class Montage_Transition : public Montage_Sequence { public: __fastcall Montage_Transition() : Montage_Sequence(ms_Transition) {} };
Qu'est-ce que vous pensez de cette organisation? Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de Montage_Track ou Montage_Preview, alors un destructeur protected et un héritage privé devraient suffire.
La question importante est de savoir si ces 2 classes ne réprésentent que des implémentations (path vers un fichier de stockage, image de previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi un comportement (capacité à se stocker physiquement accèdée par un gestionnaire de media, capacité de visualisation accèdée par une fenêtre de timeline, ...) auquel cas il serait peut être plus utile d'exposer des interfaces plutôt que des membres d'implémentation.
Michael
const enum _type_sequence { ms_Video, ms_Image, ms_Titre, ms_Transition }; Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
OK, c'est vrai
//La classe de base class Montage_Sequence { public: mutable AnsiString nom_sequence; mutable long index_ds_timeline; //Position dans le projet mutable Time_Period temps; //Temps de la séquence int left; //Coordonnées de la vignette dans le projet int top; Probablement un peu trop de trucs publics par ici qui vont induire un
couplage fort avec les utilisations de cette classe.
C'est juste pour l'exemple, ça changera par la suite...
_type_sequence type_sequence; j'imagine que type de sequence n'a pas de raison d'être modifié après
la création de l'objet ? Un méthode virtuelle pure ne serait-elle pas une meilleure solution ?
OK
Qu'est-ce que vous pensez de cette organisation? Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de Montage_Track ou Montage_Preview, alors un destructeur protected et un héritage privé devraient suffire.
Le fait de rendre le destructeur protected suffit pour empêcher une instantiation directe impossible?
La question importante est de savoir si ces 2 classes ne réprésentent que des implémentations (path vers un fichier de stockage, image de previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi un comportement (capacité à se stocker physiquement accèdée par un gestionnaire de media,
La je vois pas de quoi tu veux parler
capacité de visualisation accèdée par une fenêtre de timeline, ...) auquel cas il serait peut être plus utile d'exposer des interfaces plutôt que des membres d'implémentation.
Oui, j'ai pensé pour la classe Montage_Preview à une fonction virtuelle pure redéclarée dans les classes filles afin qu'elles gérent elles-même l'extraction du preview (depuis une image, depuis un instant T de la vidéo...)
const enum _type_sequence { ms_Video, ms_Image, ms_Titre,
ms_Transition };
Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
OK, c'est vrai
//La classe de base
class Montage_Sequence
{
public:
mutable AnsiString nom_sequence;
mutable long index_ds_timeline; //Position dans le projet
mutable Time_Period temps; //Temps de la séquence
int left; //Coordonnées de la vignette dans le projet
int top;
Probablement un peu trop de trucs publics par ici qui vont induire un
couplage fort avec les utilisations de cette classe.
C'est juste pour l'exemple, ça changera par la suite...
_type_sequence type_sequence;
j'imagine que type de sequence n'a pas de raison d'être modifié après
la création de l'objet ?
Un méthode virtuelle pure ne serait-elle pas une meilleure solution ?
OK
Qu'est-ce que vous pensez de cette organisation?
Ne dois-je pas faire de Montage_Track et de Montage_Preview des
classes virtuelles ou abstraites, vu qu'elles ne doivent pas être
instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de
Montage_Track ou Montage_Preview, alors un destructeur protected et un
héritage privé devraient suffire.
Le fait de rendre le destructeur protected suffit pour empêcher une
instantiation directe impossible?
La question importante est de savoir si ces 2 classes ne réprésentent
que des implémentations (path vers un fichier de stockage, image de
previsualisation, ...) ou est-ce qu'elles ne représenteraient pas
aussi un comportement (capacité à se stocker physiquement accèdée par
un gestionnaire de media,
La je vois pas de quoi tu veux parler
capacité de visualisation accèdée par une
fenêtre de timeline, ...) auquel cas il serait peut être plus utile
d'exposer des interfaces plutôt que des membres d'implémentation.
Oui, j'ai pensé pour la classe Montage_Preview à une fonction virtuelle
pure redéclarée dans les classes filles afin qu'elles gérent elles-même
l'extraction du preview (depuis une image, depuis un instant T de la
vidéo...)
const enum _type_sequence { ms_Video, ms_Image, ms_Titre, ms_Transition }; Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
OK, c'est vrai
//La classe de base class Montage_Sequence { public: mutable AnsiString nom_sequence; mutable long index_ds_timeline; //Position dans le projet mutable Time_Period temps; //Temps de la séquence int left; //Coordonnées de la vignette dans le projet int top; Probablement un peu trop de trucs publics par ici qui vont induire un
couplage fort avec les utilisations de cette classe.
C'est juste pour l'exemple, ça changera par la suite...
_type_sequence type_sequence; j'imagine que type de sequence n'a pas de raison d'être modifié après
la création de l'objet ? Un méthode virtuelle pure ne serait-elle pas une meilleure solution ?
OK
Qu'est-ce que vous pensez de cette organisation? Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de Montage_Track ou Montage_Preview, alors un destructeur protected et un héritage privé devraient suffire.
Le fait de rendre le destructeur protected suffit pour empêcher une instantiation directe impossible?
La question importante est de savoir si ces 2 classes ne réprésentent que des implémentations (path vers un fichier de stockage, image de previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi un comportement (capacité à se stocker physiquement accèdée par un gestionnaire de media,
La je vois pas de quoi tu veux parler
capacité de visualisation accèdée par une fenêtre de timeline, ...) auquel cas il serait peut être plus utile d'exposer des interfaces plutôt que des membres d'implémentation.
Oui, j'ai pensé pour la classe Montage_Preview à une fonction virtuelle pure redéclarée dans les classes filles afin qu'elles gérent elles-même l'extraction du preview (depuis une image, depuis un instant T de la vidéo...)
Olivier Azeau
Michael wrote:
Qu'est-ce que vous pensez de cette organisation? Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de Montage_Track ou Montage_Preview, alors un destructeur protected et un héritage privé devraient suffire.
Le fait de rendre le destructeur protected suffit pour empêcher une instantiation directe impossible?
Pas directement. Dans le cas d'une allocation sur la pile, pas de problème : l'appel au destructeur généré par le compilo provoque une erreur de compil quand le destructeur est protected. Dans le cas d'une allocation dans le tas (new/delete), il faut être ok au niveau RAII pour ne pas avoir de new sans delete (auquel cas le destructeur protected ne protège pas contre l'instanciation)
La question importante est de savoir si ces 2 classes ne réprésentent que des implémentations (path vers un fichier de stockage, image de previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi un comportement (capacité à se stocker physiquement accèdée par un gestionnaire de media,
La je vois pas de quoi tu veux parler
Tout comme tu indiques juste après que tu envisages du polymorphisme sur Montage_Preview, tu peux en avoir besoin aussi au niveau de Montage_Track mais ça dépend de ce que fait ton appli... On peut imaginer une représentation physique qui ne soit pas un simple path : par exemple, on peut avoir découpé virtuellement une gros fichier video au niveau de chaque scéne.
capacité de visualisation accèdée par une fenêtre de timeline, ...) auquel cas il serait peut être plus utile d'exposer des interfaces plutôt que des membres d'implémentation.
Oui, j'ai pensé pour la classe Montage_Preview à une fonction virtuelle pure redéclarée dans les classes filles afin qu'elles gérent elles-même l'extraction du preview (depuis une image, depuis un instant T de la vidéo...)
A mon avis, au niveau C++, ce qui est important c'est de différencier un héritage d'interface obligatoirement public d'un héritage d'implémentation qui gagne à être privé s'il n'inclut pas d'aspect comportemental vis à vis de l'extérieur de la hiérarchie.
Après on peut discuter de l'implémentation par héritage vs implémentation par composition mais ceci est une autre histoire (voire un autre troll ?)
Michael wrote:
Qu'est-ce que vous pensez de cette organisation?
Ne dois-je pas faire de Montage_Track et de Montage_Preview des
classes virtuelles ou abstraites, vu qu'elles ne doivent pas être
instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de
Montage_Track ou Montage_Preview, alors un destructeur protected et un
héritage privé devraient suffire.
Le fait de rendre le destructeur protected suffit pour empêcher une
instantiation directe impossible?
Pas directement.
Dans le cas d'une allocation sur la pile, pas de problème : l'appel au
destructeur généré par le compilo provoque une erreur de compil quand le
destructeur est protected.
Dans le cas d'une allocation dans le tas (new/delete), il faut être ok
au niveau RAII pour ne pas avoir de new sans delete (auquel cas le
destructeur protected ne protège pas contre l'instanciation)
La question importante est de savoir si ces 2 classes ne réprésentent
que des implémentations (path vers un fichier de stockage, image de
previsualisation, ...) ou est-ce qu'elles ne représenteraient pas
aussi un comportement (capacité à se stocker physiquement accèdée par
un gestionnaire de media,
La je vois pas de quoi tu veux parler
Tout comme tu indiques juste après que tu envisages du polymorphisme sur
Montage_Preview, tu peux en avoir besoin aussi au niveau de
Montage_Track mais ça dépend de ce que fait ton appli...
On peut imaginer une représentation physique qui ne soit pas un simple
path : par exemple, on peut avoir découpé virtuellement une gros fichier
video au niveau de chaque scéne.
capacité de visualisation accèdée par une
fenêtre de timeline, ...) auquel cas il serait peut être plus utile
d'exposer des interfaces plutôt que des membres d'implémentation.
Oui, j'ai pensé pour la classe Montage_Preview à une fonction virtuelle
pure redéclarée dans les classes filles afin qu'elles gérent elles-même
l'extraction du preview (depuis une image, depuis un instant T de la
vidéo...)
A mon avis, au niveau C++, ce qui est important c'est de différencier un
héritage d'interface obligatoirement public d'un héritage
d'implémentation qui gagne à être privé s'il n'inclut pas d'aspect
comportemental vis à vis de l'extérieur de la hiérarchie.
Après on peut discuter de l'implémentation par héritage vs
implémentation par composition mais ceci est une autre histoire (voire
un autre troll ?)
Qu'est-ce que vous pensez de cette organisation? Ne dois-je pas faire de Montage_Track et de Montage_Preview des classes virtuelles ou abstraites, vu qu'elles ne doivent pas être instanciées en tant que telles?
Si le besoin est juste d'empêcher une instanciation directe de Montage_Track ou Montage_Preview, alors un destructeur protected et un héritage privé devraient suffire.
Le fait de rendre le destructeur protected suffit pour empêcher une instantiation directe impossible?
Pas directement. Dans le cas d'une allocation sur la pile, pas de problème : l'appel au destructeur généré par le compilo provoque une erreur de compil quand le destructeur est protected. Dans le cas d'une allocation dans le tas (new/delete), il faut être ok au niveau RAII pour ne pas avoir de new sans delete (auquel cas le destructeur protected ne protège pas contre l'instanciation)
La question importante est de savoir si ces 2 classes ne réprésentent que des implémentations (path vers un fichier de stockage, image de previsualisation, ...) ou est-ce qu'elles ne représenteraient pas aussi un comportement (capacité à se stocker physiquement accèdée par un gestionnaire de media,
La je vois pas de quoi tu veux parler
Tout comme tu indiques juste après que tu envisages du polymorphisme sur Montage_Preview, tu peux en avoir besoin aussi au niveau de Montage_Track mais ça dépend de ce que fait ton appli... On peut imaginer une représentation physique qui ne soit pas un simple path : par exemple, on peut avoir découpé virtuellement une gros fichier video au niveau de chaque scéne.
capacité de visualisation accèdée par une fenêtre de timeline, ...) auquel cas il serait peut être plus utile d'exposer des interfaces plutôt que des membres d'implémentation.
Oui, j'ai pensé pour la classe Montage_Preview à une fonction virtuelle pure redéclarée dans les classes filles afin qu'elles gérent elles-même l'extraction du preview (depuis une image, depuis un instant T de la vidéo...)
A mon avis, au niveau C++, ce qui est important c'est de différencier un héritage d'interface obligatoirement public d'un héritage d'implémentation qui gagne à être privé s'il n'inclut pas d'aspect comportemental vis à vis de l'extérieur de la hiérarchie.
Après on peut discuter de l'implémentation par héritage vs implémentation par composition mais ceci est une autre histoire (voire un autre troll ?)
Michael
const enum _type_sequence { ms_Video, ms_Image, ms_Titre, ms_Transition }; Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
Je voudrais revenir sur ce point:
en l'état actuel des choses, je voudrais laisser cet enum qui me permet de savoir de quel type est la séquence...
En effet, je conserve toutes mes séquences dans un vecteur: std::vector<Montage_Sequence *> liste_sequences;
Par moments je suis obligé de parcourir le vecteur, et les actions sont différentes selon le type de séquence...
Ex:
for (ITE ite = liste_sequences.begin(); ite != liste_sequences.end(); ++ite) { if ((*ite)->type_sequence == ms_Image) { Montage_Image * img = dynamic_cast<Montage_Image*>(*ite); if (img) Edit_Video->Add_Screen(-1,img->Get_Path(),img->Get_Temps ().fin); } else if ((*ite)->type_sequence == ms_Video) { Montage_Video * vid = dynamic_cast<Montage_Video*>(*ite); if (vid) Edit_Video->Add_VideoTrack(-1,vid->Get_Path(),vid-> Get_Temps(),vid->Get_Rate()); } }
C'est la seule possibilité à laquelle j'ai pensé...
Y a-t-il mieux? Comme par exemple ceci:
for (ITE ite = liste_sequences.begin(); ite != liste_sequences.end(); ++ite) { Montage_Image * img = dynamic_cast<Montage_Image*>(*ite); Montage_Video * vid = dynamic_cast<Montage_Video*>(*ite);
if (img != NULL) { Edit_Video->Add_Screen(-1,img->Get_Path(),img->Get_Temps ().fin); } else if (vid != NULL) { Edit_Video->Add_VideoTrack(-1,vid->Get_Path(),vid->Get_Temps (),vid->Get_Rate()); } }
Merci d'avance...
Mike
const enum _type_sequence { ms_Video, ms_Image, ms_Titre,
ms_Transition };
Cet enum est-il nécessaire puisque l'on voit par la suite qu'il existe
une classe pour chacun des éléments ?
Je voudrais revenir sur ce point:
en l'état actuel des choses, je voudrais laisser cet enum qui me permet de
savoir de quel type est la séquence...
En effet, je conserve toutes mes séquences dans un vecteur:
std::vector<Montage_Sequence *> liste_sequences;
Par moments je suis obligé de parcourir le vecteur, et les actions sont
différentes selon le type de séquence...
Ex:
for (ITE ite = liste_sequences.begin(); ite != liste_sequences.end();
++ite)
{
if ((*ite)->type_sequence == ms_Image)
{
Montage_Image * img = dynamic_cast<Montage_Image*>(*ite);
if (img)
Edit_Video->Add_Screen(-1,img->Get_Path(),img->Get_Temps
().fin);
}
else if ((*ite)->type_sequence == ms_Video)
{
Montage_Video * vid = dynamic_cast<Montage_Video*>(*ite);
if (vid)
Edit_Video->Add_VideoTrack(-1,vid->Get_Path(),vid->
Get_Temps(),vid->Get_Rate());
}
}
C'est la seule possibilité à laquelle j'ai pensé...
Y a-t-il mieux? Comme par exemple ceci:
for (ITE ite = liste_sequences.begin(); ite != liste_sequences.end();
++ite)
{
Montage_Image * img = dynamic_cast<Montage_Image*>(*ite);
Montage_Video * vid = dynamic_cast<Montage_Video*>(*ite);
if (img != NULL)
{
Edit_Video->Add_Screen(-1,img->Get_Path(),img->Get_Temps
().fin);
}
else if (vid != NULL)
{
Edit_Video->Add_VideoTrack(-1,vid->Get_Path(),vid->Get_Temps
(),vid->Get_Rate());
}
}