C++ 代理模式-适用性和;例子

C++ 代理模式-适用性和;例子,c++,oop,design-patterns,proxy-classes,C++,Oop,Design Patterns,Proxy Classes,从这里开始: 适用性和示例 当需要控制时,代理设计模式适用 访问对象,以及需要 对对象的复杂引用。常见情况下 代理模式适用于以下情况: 虚拟代理:延迟虚拟代理的创建和初始化 对象,在需要时创建对象(用于 仅当doSomething 方法(已调用) 保护代理:代理控制对RealSubject的访问 方法,通过授予对某些对象的访问权限,同时拒绝对 其他的 智能参考:提供对特定对象的复杂访问 例如跟踪对象的引用数并拒绝 在达到某个数字时访问,以及加载对象 按需从数据库进入内存 那么,不能通过为新对象创

从这里开始:

适用性和示例

当需要控制时,代理设计模式适用 访问对象,以及需要 对对象的复杂引用。常见情况下 代理模式适用于以下情况:

虚拟代理:延迟虚拟代理的创建和初始化 对象,在需要时创建对象(用于 仅当doSomething 方法(已调用)

保护代理:代理控制对RealSubject的访问 方法,通过授予对某些对象的访问权限,同时拒绝对 其他的

智能参考:提供对特定对象的复杂访问 例如跟踪对象的引用数并拒绝 在达到某个数字时访问,以及加载对象 按需从数据库进入内存

那么,不能通过为新对象创建单个函数(构造函数除外)来创建虚拟代理吗

难道不能通过简单地将函数设置为私有并只让派生类获得访问权限来创建保护代理吗?还是通过朋友课

智能引用不能由统计已创建对象数量的静态成员变量创建吗

在哪些情况下,访问说明符和继承应首选代理方法?


我缺少的要点是什么?

代理是一个对象,作为不同的对象来添加一些控件/行为。智能指针就是一个很好的例子:它像使用原始指针一样访问对象,但它也控制该对象的生命周期。

我不是专家,但以下是我对虚拟代理的看法:如果我们通过单独的函数控制初始化,比如
bool Create()那么初始化的责任和控制权在于类的客户机。使用虚拟代理,目标是在类中保留创建控制,而客户机不知道这一点


保护代理:受保护的主体可能有不同类型的客户端,那些需要无保护/不受限制地访问所有主题方法的方法,以及其他应该允许访问方法子集的方法,因此需要保护代理。

您的问题有点抽象,我不确定我是否能很好地回答,但以下是我对每一个方法的看法。就我个人而言,我不同意这些东西中的一些是最适合这份工作的设计,但这不是你的问题,这是一个意见的问题

虚拟代理 我根本不明白你想说什么。这里模式的要点是,您可能有一个对象A,您知道它将占用100MB,但您不确定是否需要使用该对象

为了避免在需要之前为此对象分配内存,您创建了一个虚拟对象B,该对象实现了与a相同的接口,如果调用了它的任何方法,B将创建a的实例,从而避免在需要之前分配内存

保护代理 在这里,我认为您误解了该模式的使用。其思想是能够动态控制对对象的访问。例如,您可能希望类A能够访问类B的方法,除非条件C为true。我相信您可以看到,这无法通过使用访问说明符来实现

智能参考 在这里,我想你误解了智能指针的必要性。由于这是一个相当复杂的主题,我将简单地提供一个链接,指向有关它们的问题:

如果你从来没有用像C这样的语言编程,你可以自己管理你的内存,那么这也许可以解释这种混乱

我希望这有助于回答你的一些问题

编辑:

我没有注意到这是C++的标记,所以我认为你确实认识到清理动态内存的必要性。只有当您只打算拥有对象的一个实例时,单个静态引用计数才会起作用。如果您创建了2000个对象实例,然后删除了其中的1999个,那么在最后一个实例离开作用域之前,没有一个会释放内存,这显然是不可取的(即假设您跟踪了所有分配内存的位置,以便能够释放它!)

编辑2:

假设你有一门课,如下所示:

class A {
public:  
  static int refcount;

  int* allocated_memory;

  A() { 
    ++refcount;
    allocated_memory = new int[100000000];
  }

  ~A() { 
    if(! --refcount) {
      delete [] allocated_memory;
    }
  }
}
以及一些使用它的代码:

int main() {
  A problem_child;  // After this line refcount == 1
  while(true) {
    A in_scope;     // Here refcount == 2

  }                 // We leave scope and refcount == 1. 
                    // NOTE: in_scope.allocated_memory is not deleted
                    //       and we now have no pointer to it. Leak!
  return;
} 

正如您在代码refcount中看到的,对所有对象的所有引用进行计数,这会导致内存泄漏。如果需要的话,我可以进一步解释,但这实际上是一个单独的问题。

质疑是否有标准问题解决方案的替代方案是很好的。设计模式代表的解决方案为许多人所用,其优点是有经验的程序员很有可能识别出模式,从而发现维护代码更容易。然而,所有的设计都代表了权衡,模式也有成本。所以,挑战模式的使用并考虑替代方案是正确的。

在许多情况下,设计不仅仅是让代码工作,而是考虑代码的结构。哪段代码“知道”什么。您建议为虚拟Prozy移动(正如fizzbuzz所说)提供一个替代方案,将创建知识从代理移动到客户机-客户机必须“知道”才能调用Create(),从而了解类的生命周期。而使用代理,他只是创建一个对象,他将其视为工作对象,然后当代理认为它有意义时,就会进行不可见的创建。这是重构