在MATLAB中,是否可以在创建新对象之前检查对象是否已存在?

时间:2013-07-09 16:59:40

标签: matlab class constructor default-constructor

我正在试图弄清楚如何询问用户是否要用默认对象替换同一类的前一个对象,或者在调用构造函数时只使用前一个对象。

我正在寻找这两种情况下的行动:

>>obj = Obj()
'obj' already exists. Replace it with default? (y/n): y
%clear obj and call default constructor to create new obj

>>obj = Obj()
'obj' already exists. Replace it with default? (y/n): n
%cancel call of Obj()

我该怎么做?我已经搞乱了默认构造函数,但没有用。

编辑:如果它有任何区别,Obj是Handle的子类。

3 个答案:

答案 0 :(得分:4)

以下解决方案源于几种变通方法/黑客攻击,并不属于标准MATLAB的OO结构。使用谨慎

你需要:

  1. evalin()进入'caller'工作区'base' workpsace变量的名称和类
  2. 检索last executed command
  3. 提取指定变量的名称,例如regexp()
  4. 比较名称和类。如果发生总匹配,即'base'工作空间中的变量被同一类的新实例覆盖,请询问用户input()。如果用户选择保留现有对象,请使用现有对象通过evalin('caller',...)覆盖新实例。
  5. 班级foo

    classdef foo < handle
        properties
            check = true;
        end
        methods
            function obj = foo()
                % variable names and sizes from base workspace
                ws = evalin('base','whos');
    
                % Last executed command from window
                fid = fopen([prefdir,'\history.m'],'rt');
                while ~feof(fid)
                    lastline = fgetl(fid);
                end
                fclose(fid);
    
                % Compare names and classes
                outname = regexp(lastline,'\<[a-zA-Z]\w*(?=.*?=)','match','once');
                if isempty(outname);  outname = 'ans'; end
    
                % Check if variables in the workspace have same name
                idx = strcmp({ws.name}, outname);
                % Ask questions
                if any(idx) && strcmp(ws(idx).class, 'foo')
                    s = input(sprintf(['''%s'' already exists. '...
                         'Replace it with default? (y/n): '],outname),'s');
                    % Overwrite new instance with existing one to preserve it
                    if strcmpi(s,'n')
                        obj = evalin('caller',outname);
                    end
                end
            end
        end
    end
    

    班级实践:

    % create class and change a property from default (true) to false
    clear b
    
    b = foo
    b = 
      foo with properties:
        check: 1
    
    b.check = false
    b = 
      foo with properties:
        check: 0
    
    % Avoid overwriting
    b = foo
    'b' already exists. Replace it with default? (y/n): n
    
    b
    b = 
      foo with properties:
        check: 0
    

    弱点(见上文):

    1. 仅适用于cmw行和脚本执行的命令,而不适用于函数(请参阅扩展到函数调用的链接)。此外,如果在阅读 history.m
    2. 时出现问题,可能会中断
    3. 目前的正则表达式在a==b上失败。
    4. 危险,因为user input evalin()会导致潜在的安全威胁开放。即使使用regexp和字符串比较过滤输入,如果稍后再次访问该代码,该构造可能会出现问题。

答案 1 :(得分:2)

Singleton

试试这个,不确定你是否熟悉它,但这意味着,你只有一个这个特定对象的全局实例。

答案 2 :(得分:0)

您可以使用函数isobject()(请参阅文档here)来检查变量是否为对象。如果为true,则可以使用class()检查对象的类(请参阅doc here)并将其与要构建的对象的类进行比较。有点像(只是为了给你一个想法):

if isobject(obj)
    if class(obj) == myclass
        % ask to replace it or not
    else
        % create new one over the object of a different class
    end
else
    % create new one
end

如果我理解你的问题,你可能想把它作为你班级的构造函数。我认为在调用构造函数时必须传递变量名:obj = Obj(obj)