2

我试图弄清楚如何在调用构造函数时询问用户他们是想用默认对象替换同一类的前一个对象,还是简单地使用前一个对象。

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

>>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 的子类。

4

3 回答 3

4

以下解决方案源于几个变通方法/黑客,不是标准 MATLAB 的 OO 构造的一部分。谨慎使用。

你需要:

  1. evalin()进入工作空间,工作空间变量'caller'的名称和类'base'
  2. 检索最后执行的命令
  3. 提取分配变量的名称,例如regexp()
  4. 比较名称和类别。如果发生完全匹配,即'base'工作区中的变量被同一类的新实例覆盖,请向用户询问input(). 如果用户选择保留现有对象,则用现有的实例覆盖新实例evalin('caller',...)

班级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. 当前的正则表达式在a==b.
  3. 危险,因为用户输入evalin()打开了潜在的安全威胁。即使使用正则表达式和字符串比较过滤输入,如果稍后重新访问代码,该构造也可能会造成问题。
于 2013-07-11T18:52:14.240 回答
2

辛格尔顿

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

于 2013-07-11T17:26:18.243 回答
0

您可以使用该函数(请参阅此处isobject()的文档)来检查变量是否为对象。如果为真,您可以检查对象的类(请参阅此处的文档)并将其与您要构建的对象的类进行比较。类似的东西(只是给你一个想法):class()

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)

于 2013-07-09T17:22:22.953 回答