指针和面向对象编程



指针如何与面向对象编程的概念一起工作?

据我所知(请承认,我被归类为ID-10T),OOP的主要宗旨是包含并保持类中包含的管理责任(内存/实现等);但当一个对象的方法返回指针时,我们似乎在"弹出"对象。现在,有人可能需要担心:

  1. 他们应该删除指针的关联对象吗
  2. 但是如果类仍然需要该对象呢
  3. 他们能改变物体吗?如果是,如何?(我认为const可能会解决这个问题)
  4. 等等

对象的用户现在似乎需要了解更多关于类如何工作以及类对用户的期望。这感觉就像是一个"猫从袋子里出来"的场景,似乎是对OOP的一记耳光。

注意:我注意到这是一个独立于语言的问题;然而,当我在C++环境中工作时,我被提示问这个问题。

您所描述的是所有权问题。它们与对象方向正交(即独立,可以没有另一个,甚至两者都有)。如果你不使用OOP和篡改指向POD结构的指针,你也会遇到同样的问题。如果你使用OOP,但以某种方式解决了它,你就不会有问题。您可以(尝试)使用更多OOP或其他方式来解决它。

它们也与指针的使用正交(除非您挑剔并扩展了指针的定义)。例如,如果两个单独的位置将索引保存到一个数组中,并对数组进行变异、调整大小并最终删除,则会出现相同的问题。

在C++中,通常的解决方案是选择正确的智能指针类型(例如,当您希望共享对象时返回共享指针,或者返回唯一指针以表示独占所有权),以及大量的文档。事实上,后者是任何语言的关键组成部分。

一件与OOP相关的事情是封装(当然,如果没有OOP,封装也可以很好)。例如,根本不公开对象,只公开在后台查询对象的方法。或者不公开原始指针,只公开智能指针。

对于初学者。。。没有指针或参考文献。在C++中,传统上,对象被复制,并且具有(for大部分)自动存储持续时间。但复制不起作用多态对象—它们往往会被切成薄片。OO也经常意味着身份,这反过来意味着你不想要复制。所以解决方案是动态分配对象,并传递围绕指针。你用它们做什么是设计的一部分:

如果该对象在逻辑上是另一个对象的一部分,则该对象是负责其生命周期,以及接收指针的对象应该采取措施确保他们在拥有后不会使用它对象消失。(请注意,即使在具有垃圾收集。只要你有一个指向它的指针,但一旦所属对象无效,所属对象也可能变得无效。垃圾收集器不会回收内存并不能保证你指向的对象可用。)

如果对象本身是第一类实体,而不是逻辑上是另一个对象的一部分,那么它可能应该处理它本身同样,可能包含指向它的指针的其他对象必须如果它不再存在(或变得无效),则被告知。使用观察者模式是通常的解决方案。当我开始使用C++时是"关系管理"的一种时尚在其中注册关系的管理类,以及据说可以确保一切顺利。在实践中,他们要么不起作用,要么只做了简单的观察者模式,而你今天再也听不到它们了。

在大多数情况下,你的确切问题是合同的一部分每个类都必须为其每个函数建立。对于真正的OO类(实体对象),您可能永远不应该删除它们:这是生意,不是你的。但也有例外:如果你在交易例如,对于事务,已删除的对象无法回滚,因此,当一个对象决定删除自己时,它通常会注册事务管理器将此事实作为提交,一旦确定回滚就没有必要了。像对于改变对象,这是合同的问题:在很多情况下应用程序,有映射对象,用于映射对象的某种外部标识符。有了这个目标,能够修改对象。

根据我的理解和经验,它通常围绕着你试图做的事情,以及使用指针的语言(例如C++与Objective-C)。

不过,通常情况下,在C++术语中,我发现最好通过引用(甚至可能是const引用,具体取决于情况)返回对智能指针(如std::shared_ptr)的引用,或者简单地将指针隐藏在类中,如果需要由它之外的东西访问或使用,则使用getter方法,该方法复制指针并返回,或返回对指针的引用(如果允许,则对ptr的AFAIK引用仅在C++中可用)。如果有人不知道你在大多数情况下不应该删除ptr的引用(当然,如果它的释放是由类内部处理的),你真的应该三思而后行,看看他们是否准备好在你的团队中做C++的事情。

如果类成员可以被堆栈分配(即,如果它们不会占用太多内存),那么只对它们使用公共引用,同时在内部管理堆分配的对象,这是很常见的。如果需要在类之外设置类成员,可以只使用一个获取所需值的set方法,而不是直接访问它。

最新更新