有人发布了有关此模式的问题,但我没有想到要解决的问题,因此发布了我有的查询...

在上面的示例中,如果所有实例都由s_prototypes变量初始化,并且下次如果该对象的任何对象将在clone方法中被新对象替换,那么现有对象会发生什么?会造成内存泄漏吗?

据我从上面的示例了解到,有两种说法使我感到困惑

class Stooge {
public:
   virtual Stooge* clone() = 0;
   virtual void slap_stick() = 0;
};

class Factory {
public:
   static Stooge* make_stooge( int choice );
private:
   static Stooge* s_prototypes[4];
};

int main() {
   vector roles;
   int             choice;

   while (true) {
      cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
      cin >> choice;
      if (choice == 0)
         break;
      roles.push_back(
         Factory::make_stooge( choice ) );
   }

   for (int i=0; i < roles.size(); ++i)
      roles[i]->slap_stick();
   for (int i=0; i < roles.size(); ++i)
      delete roles[i];
}

class Larry : public Stooge {
public:
   Stooge*   clone() { return new Larry; }
   void slap_stick() {
      cout << "Larry: poke eyes\n"; }
};
class Moe : public Stooge {
public:
   Stooge*   clone() { return new Moe; }
   void slap_stick() {
      cout << "Moe: slap head\n"; }
};
class Curly : public Stooge {
public:
   Stooge*   clone() { return new Curly; }
   void slap_stick() {
      cout << "Curly: suffer abuse\n"; }
};

Stooge* Factory::s_prototypes[] = {
   0, new Larry, new Moe, new Curly
};
Stooge* Factory::make_stooge( int choice ) {
   return s_prototypes[choice]->clone();
}

Output
Larry(1) Moe(2) Curly(3) Go(0): 2
Larry(1) Moe(2) Curly(3) Go(0): 1
Larry(1) Moe(2) Curly(3) Go(0): 3
Larry(1) Moe(2) Curly(3) Go(0): 0
Moe: slap head
Larry: poke eyes
Curly: suffer abuse


但是当我们用make_stooge方法调用clone方法时,它将返回一个新对象,如果返回一个新对象并将其替换为现有对象,则现有对象将在此处创建内存泄漏(因为new运算符完全创建了一个单独的对象,而不在此处返回现有对象) ....

所以这件事使我对这个例子感到困惑。

最佳答案

好吧,没错,s_prototypes中的指针永远不会删除,但是至少这些对象无论如何都打算在程序的整个运行时持续使用,因此,除非需要在析构函数中执行特定的操作,如果不是在程序终止前删除它们,那不是世界末日。这远不及可能导致内存连续泄漏的代码那么糟糕,后者可能导致程序使用的内存不断增加。

如果需要,可以用静态实例代替它们,如下所示:

#include <iostream>
#include <vector>
using namespace std;

class Stooge {
public:
   virtual Stooge* clone() = 0;
   virtual void slap_stick() = 0;
   virtual ~Stooge() = default;
};

class Larry : public Stooge {
public:
   Stooge*   clone() { return new Larry; }
   void slap_stick() {
      cout << "Larry: poke eyes\n"; }
};
class Moe : public Stooge {
public:
   Stooge*   clone() { return new Moe; }
   void slap_stick() {
      cout << "Moe: slap head\n"; }
};
class Curly : public Stooge {
public:
   Stooge*   clone() { return new Curly; }
   void slap_stick() {
      cout << "Curly: suffer abuse\n"; }
};

class Factory {
public:
   static Stooge* make_stooge( int choice );
private:
   static Larry larry;
   static Curly curly;
   static Moe moe;
};

int main() {
   vector<Stooge*> roles;
   int             choice;

   while (true) {
      cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
      cin >> choice;
      if (choice == 0)
         break;
      roles.push_back(
         Factory::make_stooge( choice ) );
   }

   for (int i=0; i < roles.size(); ++i)
      roles[i]->slap_stick();
   for (int i=0; i < roles.size(); ++i)
      delete roles[i];
}

Stooge* Factory::make_stooge( int choice ) {
   switch(choice) {
   case 1:
      return larry.clone();
   case 2:
      return curly.clone();
   case 3:
      return moe.clone();
   default:
      return nullptr;
   }
}

关于c++ - 与C++中原型(prototype)模式的示例说明混淆,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41500457/

10-10 09:05