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

Konstruktor explizit aufrufen

 

Nicolas S.
Forum-Century

Forum-Century


Beiträge: 146
Anmeldedatum: 15.07.09
Wohnort: ---
Version: R2014a/b
     Beitrag Verfasst am: 29.01.2010, 18:47     Titel: Konstruktor explizit aufrufen
  Antworten mit Zitat      
Hallo zusammen,

ich versuche gerade, eine copy-Methode fuer handle-Klassen zu schreiben, die in etwa so funktionieren soll:
Code:

B = copy(A)
 

Das Problem fängt aber schon in der ersten Zeile an:
Code:

classdef hcopy < handle
    % Kopierbare handle-Klasse; Kopie eines Objekts kann mit B = copy(A)
    % erstellt werden.
    methods
        function out = copy(in)
            ci = class(in)
           
            out = eval(ci) %???????
            props = properties(in);
            for i = 1:length(props)
                out.(props{i}) = in.(props{i});
            end
        end
end
 

Wie kann ich den Konstruktor einer Klasse, deren Namen ich nur als String habe, explizit aufrufen? Muss es "eval" sein?

Viele Grüße
Nicolas
_________________

--
The programmer suggested it.
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.01.2010, 21:27     Titel:
  Antworten mit Zitat      
Der Lösung ein wenig näher; die Routine funktioniert, nur die Frage bleibt:
Code:

classdef hcopy < handle
    % Kopierbare handle-Klasse; Kopie eines Objekts kann mit B = copy(A)
    % erstellt werden.
    % Objekte der hcopy-Klasse duerfen Zirkelbezuege aufweisen, z.B.
    % "obj.Root = obj" oder "obj.Child.Root = obj" oder tiefer.
    % Bei allen anderen Klassen wird dies nicht abgefangen.
   
    % 29.01.2010: Erstellung; keine direkte Herkunft
   
    % TODO: Behandlung von properties mit "SetAccess = private" ???
    % TODO: Aufrufen des Konstruktors mit "eval" ???

    methods
        function out = copy(in)
            % Neues Objekt erzeugen; alle Properties durchgehen und
            % Kopieren; Konstanten und Abhaengige Variablen werden nicht
            % kopiert.
           
            WARN = true;

            % Input-Objekt inspizieren
            mc = metaclass(in);
            props = mc.Properties;
           
            % Neues Objekt erzeugen
            ci = class(in);
            out = eval(ci);            

           
            % Merker fuer alle Objekten der hcopy-Klasse; werden fuer
            % Rekursion gebraucht. Wenn Kopieren fertig ist werden sie
            % geloescht.
            persistent inmerker
            persistent outmerker
            if isempty(inmerker) && isempty(outmerker)
                inmerker  = {in};
                outmerker = {out};
            end
           
            % Merker fuer Rekursionstiefe; in oberster Ebene werden alle
            % statischen Variablen am Funktionsende geloescht.
            persistent recurdep
            if isempty(recurdep)
                recurdep = 0;
            else
                recurdep = recurdep + 1;
            end
           
           
            % Variablen durchgehen und kopieren. Nicht kopiert werden
            % properties mit den Attributen:
            %  - Constant
            %  - Dependent
            for i = 1:length(props)
                propname    = props{i}.Name;
                isconstant  = props{i}.Constant;
                isdependent = props{i}.Dependent;
               
                if ~( isconstant || isdependent)
                    % Konstanten muessen und koennen nicht kopiert werden
                   
                    if isa(in.(propname),'generic.hcopy') || ...
                            isa(in.(propname),'hcopy')
                        % Sonderbehandlung fuer HCOPY-Klassen wegen des
                        % erlaubten Zirkelbezugs
                       
                        % Suchen, ob der Inhalt der property schon
                        % existiert; beim ersten Fund Ruecksprung
                        idx = 0;
                        for j = 1:length(inmerker)
                            if in.(propname) == inmerker{j}
                                idx = j;
                                break
                            end
                        end
                       
                        if idx~=0
                            % Objekt kam in der Reihe schon einmal vor;
                            % Verweis auf Kopie des Objekts
                            out.(propname) = outmerker{idx};
                        else
                            % Objekt kam noch nie vor; rekursive Kopie und
                            % Orginal und Kopie merken.
                            out.(propname) = copy(in.(propname));
                            inmerker  = [ inmerker  {in.(propname)}  ];
                            outmerker = [ outmerker {out.(propname)} ];
                        end
                       
                       
                    elseif isa(in.(propname),'handle')
                        % Normale Handle-Klassen werden nicht kopiert
                        % sondern zugewiesen.
                        out.(propname) = in.(propname);
                        if WARN
                            warning('%s - property is not copied but assigned',propname)
                        end

                       
                    else
                        % Value-Klassen koennen einfach zugewiesen werden.
                        out.(propname) = in.(propname);
                    end
                end
            end
           
            % Rekursionstiefe abfragen; wenn oberste Ebene alle
            % statischen Variablen loeschen.
            if recurdep == 0
                % Aufraeumen
                clear recurdep inmerker outmerker
            else
                % Aufsteigen
                recurdep = recurdep - 1;
            end
           
        end % function

    end % methods
end
 

Ein schönes Wochenende wünscht
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: 04.02.2010, 09:30     Titel:
  Antworten mit Zitat      
Hallo,

sehr interessante Lösung. Einziger Kommentar zur Frage "muss es eval sein": jein. Im Prinzip ja, aber etwas weniger "schlimm" ist feval, welches ich in dem Fall nehme ...

Titus
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.