2012-08-28 85 views
2

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

据我了解(请认识到,我被归类为ID-10T),OOP的主要原则是包含在课堂中的遏制和管理责任(记忆/实施等);但是当一个对象的方法返回一个指针时,好像我们是'弹出'的对象。现在,有人可能需要担心:

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

看来对象的用户现在需要知道更多关于如何类作品和什么类预计用户。这感觉就像是一只“猫没有包装”的情景,似乎在OOP面前拍了拍。

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

+3

在C++ 11中,原始指针只能用于表示无所有权。 –

+1

我会研究“const vs nonconst”,“指针vs参考”,“左值vs右值”和“std :: unique_ptr”,“std :: shared_ptr”和“std :: weak_ptr”。人们抱怨C++中存在复杂的内存管理问题,这些问题在其他语言(如Java和C#)中被渲染 - 然而还有一个好处:性能。 –

回答

5

你描述的是所有权问题。这些是正交的(即独立的,你可以没有其他的或甚至两者)来面向对象。如果你不使用OOP和Pug结构的指针,你也会遇到同样的问题。如果您使用OOP但不知何故解决问题,则不存在此问题。你可以(尝试)使用更多的OOP或以其他方式解决它。

他们也是垂直指针的使用(除非你尼特挑,延长指针的定义)。例如,如果两个单独的位置将索引保存到数组中并进行变异,调整大小并最终删除数组,则会出现相同的问题。

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

一个OOP- 相关你可以做的事情是帮助这个封装(当然,你可以在没有OOP的情况下使用encaptulation)。例如,不要公开对象,只公开在查询引擎下查询对象的方法。或者不要暴露原始指针,只暴露智能指针。

+0

没有提及引用? –

+0

@MooingDuck说实话,我没有强烈的意见,应该如何在这些情况下使用引用。我唯一的猜测就是使用它们来指示非拥有的临时访问? (另外,我的答案中有一半以上是语言不可知的,很多语言甚至没有*引用。) – delnan

0

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

虽然用C++术语来说,我发现最好是通过引用返回一个对智能指针的引用(如std::shared_ptr)(根据情况甚至可以是const引用),或者直接隐藏该类中的指针,并且如果它需要被其外部的某个东西访问或使用,则使用一个getter方法,该方法复制指针并返回该指针,或者返回对指针的引用(授予,AFAIK ref-to-ptr只有在C++中才有可能)。如果有人不知道你不应删除裁判对PTR在大多数情况下(当然,如果它的重新分配由内部类处理),你应该三思而后行不论他们是否是准备好在你的团队中做C++的东西。

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

+1

我能想到一个类返回一个原始指针的唯一原因是它需要通过NULL返回一个非拥有的“引用”给一个可能不存在的成员。在所有其他情况下,应该返回一个引用,智能指针或值。没有理由返回对原始指针的引用。 –

+0

@MooingDuck - 安全关键代码要求。 –

+0

@MooingDuck - 单身呢?我宁愿能够通过引用指针来管理共享实例,而不是单独处理原始指针。这样,当我完成它时,我不必担心释放内存。 – zeboidlund

1

对于初学者...您不能有没有指针或 引用的多态性。在C++中,传统上,对象被复制,并具有(大部分为 )自动存储持续时间。但复制不适用于 多态对象—他们倾向于切片。 OO也经常意味着身份,这反过来意味着你不想复制。所以 解决方案是为动态分配对象,并围绕指针传递 。你跟他们做的是设计的一部分:

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

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

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