2017-10-09 4 views
0

alors voici la chose .. J'ai un objet qui est responsable de créer un autre objet différent, cet objet créé peut être détruit ou non (cela dépend de l'utilisateur). La partie piège est que l'objet "creator" est appelé à nouveau et si l'autre objet n'est pas détruit, cette classe ne peut pas créer cet objet, mais si l'autre objet a été détruit, cette classe doit être créée et la boucle continue.Problème avec les classes "control"

J'ai essayé 2 solutions: Variable globale comme "drapeau", cela a fonctionné très bien, mais j'ai été rôti pour l'usage variable globale; deuxième était de rendre le destructeur retourner une valeur à ce drapeau, mais je ne peux pas revenir de destructeur.

Est-ce que vous connaissez un autre moyen que la variable globale?

Vraiment apprécier l'attention, à votre santé.

+0

De quel langage de programmation s'agit-il? – melpomene

Répondre

0

Vous n'avez pas spécifié de langage de programmation, donc je vais supposer Perl (avec Moo comme boîte à outils OO).

Voici une implémentation possible de ce que vous décrivez:

use v5.14.0; 
use warnings; 

package Item { 
    use Moo; 

    has _owner => (
     is  => 'ro', 
     weak_ref => 1, 
     clearer => 1, 
    ); 

    sub detach { 
     my ($self) = @_; 
     if (my $owner = $self->_owner) { 
      $self->_clear_owner; 
      $owner->_clear_item; 
     } 
    } 

    sub BUILD { 
     my ($self) = @_; 
     say "!! constructing $self"; 
    } 

    sub DEMOLISH { 
     my ($self) = @_; 
     say "!! destroying $self"; 
    } 
} 

package Owner { 
    use Moo; 

    has item => (
     is  => 'lazy', 
     clearer => '_clear_item', 
    ); 
    sub _build_item { 
     my ($self) = @_; 
     return Item->new(_owner => $self); 
    } 
} 

my $owner = Owner->new; 
say "owner = $owner"; 
say "(1) owner->item = ", $owner->item; 
say "(2) owner->item = ", $owner->item; 
say "entering block {"; 
{ 
    my $item = $owner->item; 
    say " (3) owner->item = $item"; 
    $item->detach; 
    say " detached item = $item"; 
} 
say "} leaving block"; 
say "(4) owner->item = ", $owner->item; 
say "owner is still = $owner"; 

Quand je lance ce code, il produit la sortie suivante:

owner = Owner=HASH(0x23e52f8) 
!! constructing Item=HASH(0x23e4950) 
(1) owner->item = Item=HASH(0x23e4950) 
(2) owner->item = Item=HASH(0x23e4950) 
entering block { 
    (3) owner->item = Item=HASH(0x23e4950) 
    detached item = Item=HASH(0x23e4950) 
!! destroying Item=HASH(0x23e4950) 
} leaving block 
!! constructing Item=HASH(0x23eb328) 
(4) owner->item = Item=HASH(0x23eb328) 
owner is still = Owner=HASH(0x23e52f8) 
!! destroying Item=HASH(0x23eb328) 

L'idée est que la classe Owner a une Attribut item (qui stocke une instance de la classe Item). Cet attribut est paresseux, donc il n'est construit que sur demande (la première fois que vous l'utilisez).

Comme vous pouvez le voir en regardant les owner->item lignes 1, 2 et 3, aucun nouvel objet n'est construit: $owner se souvient de ses item. Cependant, il est possible de détruire item explicitement en appelant $owner->item->detach. Cela est possible car chaque instance de Item a un attribut (facultatif) _owner; c'est-à-dire que chaque article se souvient de son propriétaire. C'est une référence faible car sinon nous aurions un cycle de référence (le propriétaire garde l'élément en vie, l'objet garde le propriétaire en vie). Lorsque nous appelons $item->detach, $item se retire automatiquement de son propriétaire (s'il en a toujours un). Il est alors automatiquement détruit dès que toute autre référence à celui-ci a disparu (dans l'exemple, cela se produit lorsque la variable locale $item cesse d'exister à la fin de son bloc).

$owner, ayant été réinitialisé à son état initial, puis recrée automatiquement un nouveau item la prochaine fois que cela est nécessaire.

+0

c'est C++, mais j'ai fait undestand la logique .. je ne pouvais pas penser à autre chose Va essayer d'adapter ce code à C++. Merci frère, j'apprécie vraiment – DearChild