2

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

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

  1. 他们应该删除指针的关联对象吗?
  2. 但是如果类仍然需要这个对象呢?
  3. 他们可以改变对象吗?如果是这样,怎么做?(我知道const可能会解决这个问题)
  4. 等等……

似乎该对象的用户现在需要更多地了解该类的工作方式以及该类对用户的期望。感觉就像是“猫从袋子里出来”的场景,似乎是在打 OOP 的耳光。

注意:我注意到这是一个独立于语言的问题;但是,在 C++ 环境中工作时,系统提示我提出这个问题。

4

3 回答 3

5

What you describe are ownership issues. These are orthogonal (i.e. independent, you can have either without the other or even both) to object orientation. You have the same issues if you do not use OOP and juggle pointers to POD structs. You don't have the issue if you use OOP but solve it somehow. You can (try to) solve it using more OOP or in another way.

They are also orthogonal to the use of pointers (unless you nit pick and extend the definition of pointer). For example, the same issues arise if two separate places hold indices into an array and mutate, resize and ultimately delete the array.

In C++, the usual solution is to select the right smart pointer type (e.g. return a shared pointer when you wish to share the object, or a unique pointer to signify exclusive ownership), along with extensive documentation. Actually, the latter is a key ingredient in any language.

One OOP-related thing you can do to help this is encapsulation (of course, you can have encaptulation just fine without OOP). For instance, don't expose the object at all, only expose methods which query the object under the hood. Or don't expose raw pointers, only expose smart pointers.

于 2012-08-28T17:56:29.903 回答
1

对于初学者......你不能没有指针或引用的多态性。在 C++ 中,传统上,对象是被复制的,并且(在大多数情况下)具有自动存储持续时间。但是复制不适用于多态对象——它们往往会被切片。而 OO 也常常意味着身份,这反过来又意味着你不想要复制。所以解决方案是动态分配对象,并传递指针。你用它们做什么是设计的一部分:

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

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

在大多数情况下,您的精确问题是每个类必须为其每个功能建立的契约的一部分。对于真正的 OO 类(实体对象),您可能永远不应该删除它们:那是业务,而不是您的业务。但也有例外:如果你在处理事务,例如,一个被删除的对象不能回滚,所以当一个对象决定删除自己时,它通常会向事务管理器注册这个事实,事务管理器会将它作为一部分删除提交后,一旦确定回滚就没有必要了。至于改变对象,那是合约的问题:在很多应用程序中,都有映射对象,用于将某种外部标识符映射到对象。通常,目标是能够修改对象。

于 2012-08-28T18:01:11.677 回答
0

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

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

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

于 2012-08-28T17:38:16.923 回答