Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 实例将自身与新实例热交换_C++_Design Patterns_Polymorphism - Fatal编程技术网

C++ 实例将自身与新实例热交换

C++ 实例将自身与新实例热交换,c++,design-patterns,polymorphism,C++,Design Patterns,Polymorphism,我有一些动作。。。查看、编辑、签出等。业务逻辑规定,如果文档已签出,则所有视图都将转换为编辑 有没有一种简洁的OO方法可以做到这一点: class Action { public: Document document; virtual void execute(); }; class View, Edit, Checkout : public Action; View::execute() { if (document.isCheckedOut) { delete th

我有一些动作。。。查看、编辑、签出等。业务逻辑规定,如果文档已签出,则所有视图都将转换为编辑

有没有一种简洁的OO方法可以做到这一点:

class Action
{
public:
  Document document;
  virtual void execute();
};
class View, Edit, Checkout : public Action;

View::execute()
{
  if (document.isCheckedOut)
  {
    delete this;
    this = new Edit;
    this->execute();
  }
  /* execute view */
}
更新:你们对此有何看法:

class Action
{
public:
  static int type;
  Document document;
  virtual void execute();
  static Action* construct(int type, Document document) = 0;
private:
  Action();
};
class View, Edit: public Action;

Action* View::construct(Document document)
{
  if (document.isCheckedOut)
    return new Edit(document);
  return new View(document);
}

Action* Edit::construct(Document document)
{
  return new Edit(document);
}

void onViewButton(Document document)
{
  Action *action = View::construct(document);
  action->execute();
  delete action;
}

没有办法像那样重新分配“this”指针。您可以使用智能指针实现通过添加一层间接寻址来执行类似的操作

class action_ptr  
{
  Action* m_Data;
public:
  action_ptr(Action* value)
  {
     m_Data = value;
  }

  Action* operator->()
  {
      if(m_Data->isView() && m_Data->isCheckedOut())
      {
        delete m_Data;
        m_Data = new Edit();
      }
      return m_Data;
  }
};


 // usage
action_ptr pAction(new View());
pAction->DoViewStuff();
pAction->Checkout();
pAction->OtherStuff();  // If isCheckedOut returned true, this now magically operates on an Edit instead!

这绝不是一个完整的实现,只是一个例子——内存泄漏和许多缺失的函数。

我可能会用策略模式解决这个问题,其中策略有一个转换成员函数。大致如下(省略了无趣的代码部分):

struct action\u策略{
虚拟~action_strategy();
虚拟行动策略*转换策略(文档常量和文档);
虚空执行()=0;
};
集体诉讼{//Hur,Hur:D
公众:
//用堆分配策略构造
行动(行动、战略*战略);
void execute(){
策略重置(策略->转换策略(单据);
策略->执行();
}
私人:
文件文件;
std::自动ptr策略;
};
//默认设置:什么都不做
行动策略*行动策略::转换策略(文档常量和文档){
归还这个;
}
课堂观点:公共行动策略{
//必要时超载
虚拟行动策略*转换策略(文档常量和文档);
};
操作策略*视图::转换策略(文档常量和文档){
如果(文件已签出()){
返回新编辑();
}
归还这个;
}

最好说明它试图解决的问题。您可能需要检查一些众所周知的模式,如Proxy(),界面,委托;在尝试做其他事情之前,满足您的需要。为什么不检查一下所有
操作的存储位置,并将所有
视图
替换为
编辑
或其他什么。很难弄清楚您在做什么。将其想象成一种Pimpl模式可能更有意义校正对象会根据特定条件被调出,而不是将其称为智能指针。但最终结果是类似的。请使用
boost::scoped_ptr
std::unique_ptr
而不是简单的
操作*
,这样可以避免明显的内存泄漏。
struct action_strategy {
  virtual ~action_strategy();

  virtual action_strategy *convert_strategy(document const &doc);
  virtual void execute() = 0;
};

class action { // Hur, hur :D
public:
  // construct with heap-allocated strategy
  action(action_strategy *strategy);

  void execute() {
    strategy_.reset(strategy_->convert_strategy(doc_);
    strategy_->execute();
  }

private:
  document doc_;
  std::auto_ptr<action_strategy> strategy_;
};

// Default: do nothing
action_strategy *action_strategy::convert_strategy(document const &doc) {
  return this;
}

class view : public action_strategy {
  // overload as necessary
  virtual action_strategy *convert_strategy(document const &doc);
};

action_strategy *view::convert_strategy(document const &doc) {
  if(doc.is_checked_out()) {
    return new edit();
  }

  return this;
}