WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Luke, ich bin Dein Vater!

 

Nicolas S.
Forum-Century

Forum-Century


Beiträge: 146
Anmeldedatum: 15.07.09
Wohnort: ---
Version: R2014a/b
     Beitrag Verfasst am: 28.09.2009, 10:52     Titel: Luke, ich bin Dein Vater!
  Antworten mit Zitat      
Hallo zusammen,

manchmal sieht es so aus, als sei ich der einzige im GoMatlab-Forum, der mit der OOP so seine Problemchen hat- oder daß OOP unter Matlab in anderen Foren besser aufgehoben ist. Oder ist das alles noch nicht so verbreitet?

Wie dem auch sei: Im Moment stellt sich mir die Frage, wie ich einem Objekt beibringe, wer seine Eltern sind. Oder konkreter:
Ich habe zwei Klassen foo und bar.
Code:

classdef foo < handle
 properties
    sets;
 end
 methods
   % Konstruktor
   function obj = foo();
       obj.sets = repmat(bar(obj),1,10);
    end
 end
end
 

Code:

classdef bar < handle
 properties
    data;
    parent;
 end
 methods
   % Konstruktor
   function obj = bar();
       obj.data = [];
       obj.parent = ????
    end
 end
end
 

Jetzt die interessierende Frage: Wie kann ich dafür sorgen, daß ein Objekt der Klasse bar immer weiß, von welchem Objekt es erzeugt wurde?
Also sollte das in etwas so zu bedienen gehen:
Code:

a = foo;
b = a.sets(1);
c = b.parent;
a == c
ans =
  true
 

Das Problem sieht von meiner Seite so aus: Unpraktischerweise muss der Konstruktor ja auch ohne Parameter aufgerufen werden können, sonst funktioniert z.B. repmat nicht. (lautete der Konstruktor so:
Code:

% Konstruktor
function obj = bar(parentobj);
       obj.data = [];
       obj.parent = parentobj;
    end
 

würde der Konstruktor bei der Konstruktion obj.sets = repmat(bar(obj),1,10); ja nur bei der ersten Instanz von bar durchlaufen. Die jüngeren Geschwister von sets(1) kennten dann ihre Eltern nicht.)

Kennt jemand eine Lösung für dieses Dilemma?

Viele Grüße
Nicolas
_________________

--
The programmer suggested it.
Private Nachricht senden Benutzer-Profile anzeigen


Andreas Goser
Forum-Meister

Forum-Meister


Beiträge: 3.654
Anmeldedatum: 04.12.08
Wohnort: Ismaning
Version: 1.0
     Beitrag Verfasst am: 28.09.2009, 11:50     Titel:
  Antworten mit Zitat      
Zitat:
manchmal sieht es so aus, als sei ich der einzige im GoMatlab-Forum, der mit der OOP so seine Problemchen hat- oder daß OOP unter Matlab in anderen Foren besser aufgehoben ist. Oder ist das alles noch nicht so verbreitet?


Letzteres. Erstens ist es noch recht neu und zweitens finden viele Anwender es gerade so erfrisched einfach drauf los programmieren zu können...

Ich versuche mittelfristig jemanden zu finden der sich von MathWorks Seite aus für diese Forum und das OOP / MCOS Thema interessiert. Aber auch wir machen das alles nur nebenher. Zur Info: 5 der Top 2o Poster hier sind MathWorks Mitarbeiter.

Kurzfristig: Wenn die Probleme hier nicht gelöst werden können hilft entweder der Schwenk in die englische Sprache oder der Technische Support.

Andreas
Private Nachricht senden Benutzer-Profile anzeigen E-Mail senden
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.495
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 28.09.2009, 12:10     Titel:
  Antworten mit Zitat      
Hallo,

Ich denke, das Problem liegt daran, was genau hier bei REPMAT passiert. Im Zusammenhang mit Handle-Objekten ist das ja doch nicht so einfach. Auf Umwegen bin ich darauf gekommen, dass es mit

Code:
obj.sets = repmat({bar(obj)},1,10);

zu funktionieren scheint.

Hilft dir das weiter?

Grüße,
Harald
(einer der von Andreas angesprochenen 5 Wink )
Private Nachricht senden Benutzer-Profile anzeigen
 
Nicolas S.
Themenstarter

Forum-Century

Forum-Century


Beiträge: 146
Anmeldedatum: 15.07.09
Wohnort: ---
Version: R2014a/b
     Beitrag Verfasst am: 29.09.2009, 09:38     Titel:
  Antworten mit Zitat      
Hui, zuerst dachte ich, der Quelltextvorschlag sei magisch. Aber frickeln wir das mal auseinander. Die einfachste Klasse, die ich mir vorstellen könnte, wäre so:
Code:

classdef foo < handle
    properties
        dat
    end
   
    methods
        function obj = foo(varargin)
            varargin            
        end
    end
end
 

Erzeuge ich ein Array von Objekten (wie üblich):
Code:

arr = repmat(foo('a'),1,4)

varargin =

    'a'


varargin =

     {}


arr =

  1x4 foo handle

  Properties:
    dat
 

Der Konstruktor wird also zweimal aufgerufen, beim zweiten Mal ohne Parameter.
Beim "magischen" Vorschlag:
Code:

arr = repmat({foo('a')},1,4)

varargin =

    'a'


arr =

    [1x1 foo]    [1x1 foo]    [1x1 foo]    [1x1 foo]
 

Der Konstruktor wird also nur einmal aufgerufen.
Code:

In arr wurde also ein cell-Array immer des gleichen Objektes gespeichert:
Code:

>> arr{1}.dat = 1;
>> arr{2}.dat

ans =

     1
 

Da der Konstruktor nur einmal aufgerufen wurde, ist das Array einfach mit Kopien des handles des gleichen Objektes gefüllt - klar, repmat wirkt ja auch auf ein cell array und nicht auf das Objekt.

Für eine value-Klasse wäre das wahrscheinlich die Lösung gewesen; für eine handle-Klasse leider nicht.

Aber es war mal eine nette kleine Knobelaufgabe.

Viele Grüße
Nicolas
_________________

--
The programmer suggested it.
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.495
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 29.09.2009, 09:53     Titel:
  Antworten mit Zitat      
Hallo nochmal,

eine andere Variante wäre

Code:
classdef foo < handle
 properties
    sets;
 end
 methods
   % Konstruktor
   function obj = foo();
       for I=1:10
            obj.sets{I} = bar(obj);
       end
    end
 end
end


Die FOR-Schleife ist zwar nicht schön, aber ich denke, das Problem lag hier wirklich im Verhalten von REPMAT.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Nicolas S.
Themenstarter

Forum-Century

Forum-Century


Beiträge: 146
Anmeldedatum: 15.07.09
Wohnort: ---
Version: R2014a/b
     Beitrag Verfasst am: 29.09.2009, 10:01     Titel:
  Antworten mit Zitat      
Andreas Goser hat Folgendes geschrieben:

Ich versuche mittelfristig jemanden zu finden der sich von MathWorks Seite aus für diese Forum und das OOP / MCOS Thema interessiert. Aber auch wir machen das alles nur nebenher. Zur Info: 5 der Top 2o Poster hier sind MathWorks Mitarbeiter.

Kurzfristig: Wenn die Probleme hier nicht gelöst werden können hilft entweder der Schwenk in die englische Sprache oder der Technische Support.

Andreas


Die Mitmacher beim Matlab newreader konnte ich schon als sehr hilfreich und qualifiziert kennenlernen. Aber man will sich ja mit seinen OOP-Anfängerfragen nicht gerade vor einem weltweiten Publikum blamieren Wink .

Daß hier Mitarbeiter schreiben, ist ja in manchen Fällen recht offensichtlich: Ort "Ismaning" deutet es ja schon an. Finde ich toll, daß man euch dazu begeistern kann!

Das das ganze OOP unter Matlab wohl noch ein Nischendasein fristet, habe ich mir schon gedacht. Eigentlich hat man ja erst sein R2009a die Chance, mit ordentlichen Fehlermeldungenr Fehler zu finden. Und auch die Möglichkeiten haben sich von 2007b bis 2009a steil verbessert.

Mal sehen, was die Zukunft bringt. Ich hoffe ja immer noch auf eine bessere Fehlerdarstellung von Fehlern innerhalb von events/callbacks. Wink

Viele Grüße
Nicolas
_________________

--
The programmer suggested it.
Private Nachricht senden Benutzer-Profile anzeigen
 
Titus
Forum-Meister

Forum-Meister


Beiträge: 871
Anmeldedatum: 19.07.07
Wohnort: Aachen
Version: ---
     Beitrag Verfasst am: 29.09.2009, 11:55     Titel:
  Antworten mit Zitat      
Hallo,

so dumm ich den Spruch in der Schule damals fand: es gibt keine dummen Fragen, nur dumme Antworten.
Das Thema ist in MATLAB noch verhältnismäßig neu, trotzdem wird es auch im großen Stil schon von Kunden eingesetzt. Ich betreue einen Kunden, der gerade ein System entwickelt, das bereits aus über 100 Klassen mit mehr als 50000 Zeilen Code besteht ...

Ciao,
Titus

PS: übrigens gibt es auch in Aachen eine Niederlassung von The MathWorks Wink
Private Nachricht senden Benutzer-Profile anzeigen
 
Beehive
Forum-Newbie

Forum-Newbie


Beiträge: 1
Anmeldedatum: 13.02.08
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 30.09.2009, 07:12     Titel:
  Antworten mit Zitat      
Titus hat Folgendes geschrieben:
Hallo,
Ich betreue einen Kunden, der gerade ein System entwickelt, das bereits aus über 100 Klassen mit mehr als 50000 Zeilen Code besteht ...



Ist doch nicht viel?
Wir arbeiten derzeit aber noch nicht mit OOP, sondern haben damals uns eben etwas überlegt, wie wir OOP in Matlab herein bekommen... und arbeiten so zu sagen mit unserem "framework" in Matlab und haben mittlerweile so viele Module, Funktionen und Klassen... das wir derzeit nicht umsteigen können Sad

Obwohl es auf Dauer einfacher wäre...
Private Nachricht senden Benutzer-Profile anzeigen
 
Nicolas S.
Themenstarter

Forum-Century

Forum-Century


Beiträge: 146
Anmeldedatum: 15.07.09
Wohnort: ---
Version: R2014a/b
     Beitrag Verfasst am: 30.09.2009, 09:52     Titel: Luke hat seinen Vater gefunden
  Antworten mit Zitat      
Hallo zusammen,

das Ganze habe ich jetzt wie folgt realisiert (ungefähr, das eigentliche Ziel war ein anderes):

Klasse 1:
Code:

classdef face < handle
   
    %% Flaeche    
    % Nur Testbeispiel: Eine Flaeche hat vier Eckpunkte und vier Kanten.
    % Jede Kante kann nur zu einer Flaeche gehoeren!
    properties
        data;
        borders;
    end
   
    methods
        % Konstruktor
        function obj = face(inp)
            if all(size(inp) == [2 4])
                obj.data = inp;
           
                obj.borders = repmat(border,1,4);
                for i = 4:-1:1
                   obj.borders(i) = border();
                   obj.borders(i).parent = obj;
                   temp = [inp inp(:,1)];
                   obj.borders(i).data = temp(:,[i i+1]);                    
                end
               
            else
                error('Input must be of size 2x4 ')
            end
           
        end      
       
        function h = plot(obj,varargin)
           h = patch(obj.data(1,:), obj.data(2,:),'g',varargin{:});
        end
    end
end

 


Klasse 2 (der interessantere Teil):
Code:

classdef border < handle
   
    %% Rand (border)
    properties
        data;
        parent;
    end
   
    methods
        % Konstruktor
        function obj = border()
            % Hier passiert nix. Und das ist gut.
        end
       
        function set.parent(obj,inp)
            % Der Parent-Parameter darf nur einmal gesetzt werden, direkt
            % nach der Erzeugung, aber nicht mehr geaendert!
            if isempty(obj.parent);
                if strcmpi(class(inp),'face')
                    obj.parent = inp;
                else
                    error('parent of border must be of class face')
                end
            else
                % Da der 'parent'-Parameter, einmal gesetzt, einen handle
                % auf das Mutterobjekt beinhalted, kann der
                % 'parent'-Parameter mit:
                % obj.parent = 'a'
                % nicht wieder geaendert werden- denn hier wird jetzt 'a'
                % in das Mutterobjekt geschrieben, und nicht etwa die
                % 'parent'-property auf 'a' gesetzt.
                % Diese Verhalten ist, obwohl durch 'Zufall' entstanden,
                % gewünscht - Niemand kann seine Eltern wechseln.
                % Der folgende Zweig sollte also nie erreicht werden
                % koennen.
                error(' border - the author never anticipated this branch to be reached.')
            end          
        end
       
        function h = plot(obj,varargin)
            h = plot(obj.data(1,:),obj.data(2,:));
           
        end
       
    end
end
 

Zwar muss jetzt jedes Objekt direkt nach der Erzeugung sein Mutterobjekt beigebracht bekommen- aber das Ganze ist dann fest verbunden. Ist nicht weit vom Anfang entfernt (eigentlich wurde die Geschichte mit repmat und dem Konstruktor nur umgangen), dafür sieht das Ganze nach dem Speichern und wieder laden auch wie vorher aus.

Bonusfrage: Gäbe es jetzt noch eine Möglichkeit, das Mutterobjekt zu ändern, wenn ich das wollte? (Siehe Kommentar im set.parent-Block)

Denn:
Code:

>> a = face([1 2 3 4; 1 0 0 1]);
>> a.borders
ans =
  1x4 border handle
  Properties:
    data
    parent

>> a.borders.parent = 4 % <===
 

Denn in der markierten Zeile würde die set-function von borders ja nie wieder aufgerufen- denn es geht ja direkt in a. (Die Zeile mündet natürlich in einer sinnvollen Fehlermeldung.)

Viele Grüße
Nicolas
_________________

--
The programmer suggested it.
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.