16 votes

Comment obtenir des variables membres statiques dans les classes MATLAB ?

Existe-t-il un moyen de définir des variables membres statiques dans les classes MATLAB ?

Cela ne fonctionne pas :

classdef A

    properties ( Static )
        m = 0;
    end
end

Il suggère d'utiliser le mot-clé "Constant" au lieu de "Static", les propriétés constantes ne pouvant être modifiées. Je veux une variable commune à tous les objets de la classe A et je veux pouvoir modifier cette variable dans les méthodes de la classe A .

J'ai donc besoin d'une variable membre statique privée. Existe-t-il un moyen de l'obtenir dans MATLAB ?


On a découvert qu'il est possible de contourner le problème. l'utilisation de variables persistantes dans les fonctions membres statiques.

Dans ce cas, vous devez faire hériter toutes vos classes d'une classe de base comme la suivante.

classdef object < handle

    properties ( GetAccess = 'public', SetAccess = 'private' )
        id
    end

    methods ( Access = 'protected' )
        function obj = object()
            obj.id = object.increment();
        end
    end

    methods ( Static, Access = 'private' )
        function result = increment()
            persistent stamp;
            if isempty( stamp )
                stamp = 0;
            end
            stamp = stamp + uint32(1);
            result = stamp;
        end
    end  
end

17voto

Mikhail Points 3393

Vous ne pouvez pas, c'est voulu. Vous devez utiliser un persistent variable (technique de MATLAB telle que 1980 appliquée en 2011) !

Pour être complet, je dois mentionner qu'il existe depuis 2010b une solution non documentée et probablement plus supportée. static modificateur de propriété.

Pour plus d'informations, voir aquí la réponse de Dave Foti Responsable du groupe MATLAB OO :

Dans MATLAB, les classes peuvent définir Constant mais pas de propriétés "statiques" au sens d'autres langages comme comme le C++. Il y a eu des versions qui ont expérimenté les propriétés Les propriétés "statiques" et l'attribut attribut non documenté subsiste depuis l'époque. Cependant, l'attribut Static est non documenté, ne doit pas être utilisé et sera probablement supprimé dans une prochaine MATLAB. La version R2008a l'implémente comme synonyme de Constant et ne fournit aucune fonctionnalité supplémentaire le comportement documenté des propriétés Constant propriétés.

Les propriétés constantes ne peuvent pas être modifiées à partir de la valeur initiale spécifiée dans la déclaration de la propriété. Il y a quelques raisons pour lesquelles MATLAB fonctionne de la manière dont il fonctionne. Tout d'abord, MATLAB a des règles de longue date selon lesquelles les variables ont toujours la priorité sur les noms des fonctions et des classes et que les les instructions d'affectation introduisent un variable s'il n'en existe pas déjà une. Ainsi, toute expression de la forme "A.B = C" introduira une nouvelle variable A qui est un tableau struct contenant un champ B dont la valeur est C. champ B dont la valeur est C. Si "A.B = C" pouvait pouvait faire référence à une propriété statique de la de la classe A, alors la classe A aurait la classe A prendrait le pas sur la variable A, ce qui serait une incompatibilité incompatibilité avec les versions antérieures de MATLAB. Cela signifierait qu'un fichier m contenant l'affectation d'affectation "A.B = C" pourrait voir sa par l'introduction d'une classe nommée d'une classe nommée A quelque part sur le MATLAB. Les programmeurs MATLAB ont toujours pu compter sur les instructions d'affectation introduisant des variables qui qui font de l'ombre à toute autre utilisation du même nom.

S sont rarement utilisées dans d'autres classes sauf en tant que données privées au sein de la ou comme constantes publiques. Par exemple, une par exemple, une étude de plusieurs bibliothèques de classes Java a révélé que toutes les classes statiques publics étaient également finaux. Dans MATLAB, les propriétés Constant peuvent être être utilisées comme les champs "public final static" en Java. en Java. Pour les données internes à une MATLAB dispose déjà de variables persistantes qui peuvent être créées à l'intérieur de de méthodes privées ou protégées ou de fonctions locales utilisées en privé par une classe. Il existe également de bonnes raisons d d'éviter les données statiques dans MATLAB possible. [ ] il peut être difficile d'utiliser la même classe dans plusieurs applications car les données statiques peuvent être une [ ] applications. Dans d'autres langages, ce problème est moins important, car les les différentes applications sont séparément compilées séparément dans des exécutables différents processus avec différentes différentes copies des données statiques de la classe. Dans MATLAB, de nombreuses différentes peuvent être exécutées dans le processus même processus et dans le même environnement avec un seule copie de chaque classe.

11voto

jung Points 47

Voici une méthode directe pour créer une propriété statique dans Matlab. La seule différence entre cette implémentation et une hypothétique (mais impossible ; voir la réponse de Mikhail) vraie propriété statique est la syntaxe pour définir la variable membre.

classdef StaticVarClass
    methods (Static = true)
        function val = staticVar(newval)
            persistent currentval;
            if nargin >= 1
                currentval = newval;
            end
            val = currentval;
        end
    end
end

La propriété statique staticVar peut maintenant être lue via :

StaticVarClass.staticVar

...et être mis en place via :

StaticVarClass.staticVar(newval);

Voici, par exemple, le résultat attendu d'un test de cette fonctionnalité :

>> StaticVarClass.staticVar
  ans =
      []
>> StaticVarClass.staticVar('foobar')
  ans =
      foobar
>> StaticVarClass.staticVar
  ans =
      foobar
>> 

Cette approche fonctionne tout aussi bien pour les propriétés statiques privées comme vous l'avez demandé, mais le code de démonstration est un peu plus long. Notez qu'il ne s'agit pas d'une classe handle (bien qu'elle fonctionnerait parfaitement sur une classe handle également).

classdef StaticVarClass
    methods (Access = private, Static = true)
        function val = staticVar(newval)
            persistent currentval;
            if nargin >= 1
                currentval = newval;
            end
            val = currentval;
        end
    end

    methods
        function this = setStatic(this, newval)
            StaticVarClass.staticVar(newval);
        end

        function v = getStatic(this)
            v = StaticVarClass.staticVar;
        end
    end
end

...et le test :

>> x = StaticVarClass
  x = 
      StaticVarClass with no properties.
      Methods
>> x.getStatic
  ans =
      []
>> x.setStatic('foobar')
  ans = 
      StaticVarClass with no properties.
      Methods
>> x.getStatic
  ans =
      foobar
>>

1voto

Hadi Points 619

(pour information) il y a une (autre ?) façon de créer des données de type statique dans matlab

Supposons que vous ayez une classe "handle" dont le nom est "car" si vous voulez que la classe "voiture" ait des données statiques, vous pouvez construire une autre classe "handle" et l'utiliser dans la composition "throw" de la classe "voiture", cette dernière classe fonctionne comme une donnée statique pour la classe "voiture".

classdef car<handle 
    properties 
         static_data:STATIC_DATA_HOLDER;
    end
end

classdef STATIC_DATA_HOLDER<handle
    properties
        data
    end
end

Ainsi, lorsque vous créez la première instance d'une classe de voiture, une instance de STATIC_DATA_HOLDER est créée et lorsque vous créez la deuxième instance de la classe de voiture, elle utilise la classe STATIC_DATA_HOLDER précédemment créée.

ce code a été testé avec "MATLAB 2013b".

0voto

Elmar Zander Points 286

Une autre solution pour obtenir des propriétés statiques consiste à utiliser le fait que le code d'initialisation des variables membres n'est exécuté qu'une seule fois lors du chargement du fichier de classe. Cela signifie que si vous avez une définition comme

classdef foo
    properties
        stuff = some_function()
    end
end

entonces some_function n'est invoqué qu'une seule fois, et s'il renvoie un objet de type classe, celui-ci sera partagé par toutes les instances. J'ai ajouté un exemple de mise en œuvre qui montre comment cela peut être utilisé :

classdef ClassWithStaticMembers
    properties
        classvars = StaticVarContainer('foo', 0, 'bar', 2);
        othervar
    end
    methods
        function obj=ClassWithStaticMembers(var)
            obj.othervar = var;
        end
    end 
end

classdef StaticVarContainer < dynamicprops
    methods
        function obj=StaticVarContainer(varargin)
            for i=1:2:numel(varargin)
                obj.addprop(varargin{i});
                obj.(varargin{i}) = varargin{i+1};
            end
        end
    end
end

Si vous exécutez cet exemple de code

obj1 = ClassWithStaticMembers(3);
obj2 = ClassWithStaticMembers(5);
obj1.classvars.foo = [2,3];

obj1.othervar
obj1.classvars

obj2.othervar
obj2.classvars

vous verrez, que classvars est en effet partagée. Je pense que cette solution est bien plus agréable que l'utilisation de variables persistantes dans les fonctions, puisque vous pouvez réutiliser la fonction StaticVarContainer aussi souvent que vous le souhaitez, c'est plus facile à utiliser, et de plus, vous voyez directement l'initialisation des variables statiques dans la section des propriétés.

Pour obtenir le résultat souhaité dans la question de l'OP (c'est-à-dire implémenter un compteur d'objets), la propriété partagée peut être modifiée comme suit Constant afin qu'il puisse être référencé sans avoir d'instance à portée de main :

classdef ClassWithCounter
    properties (Constant)
        static = StaticVarContainer('counter', 0);
    end
    methods
        function obj=ClassWithCounter()
            obj.static.counter = obj.static.counter + 1;
        end
    end 
end

clear all
obj1 = ClassWithCounter();
obj2 = ClassWithCounter();
obj3 = ClassWithCounter();

ClassWithCounter.static.counter

Il est à noter que le Constant signifie seulement que, par exemple, l'attribut obj1.static ne peut pas être modifié, mais il n'affecte pas le obj1.static.counter qui n'est pas constante et peut être réglée au gré du cœur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X