为什么使用指针比使用对象本身更好?_最新动态_新闻资讯_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 新闻资讯 > 最新动态 > 为什么使用指针比使用对象本身更好?

为什么使用指针比使用对象本身更好?

 2014/3/26 19:07:05    程序员俱乐部  我要评论(0)
  • 摘要:英文原文:WhyshouldIuseapointerratherthantheobjectitself?问题:为什么使用指针比使用对象本身更好?我是一名Java程序员,最近开始学习使用C++中的对象。有个问题我一直觉得很困惑:那就是为什么人们更喜欢使用指向对象的指针而不是对象本身。比如:这样声明:Object*myObject=newObject;而不是:ObjectmyObject;使用函数的时候也是如此,假设有个函数为testFunc(),使用时可以这样:myObject.testFunc
  • 标签:使用 什么 为什么 更好 指针
class="topic_img" alt=""/>

  英文原文:Why should I use a pointer rather than the object itself?

  问题:为什么使用指针比使用对象本身更好?

  我是一名 Java 程序员,最近开始学习使用 C++ 中的对象。有个问题我一直觉得很困惑:那就是为什么人们更喜欢使用指向对象的指针而不是对象本身。比如:

  这样声明:Object *myObject = new Object;

  而不是:Object myObject;

  使用函数的时候也是如此,假设有个函数为 testFunc (),使用时可以这样:

myObject.testFunc ();

  但一般这样调用:

myObject->testFunc ();

  但是我不知道为什么要这样做,我想可能是因为我们直接访问了内存地址,所以能提高效率和运行速度。我理解的对吗?

  最佳答案:

  很不幸,你看的很多讲的都是动态分配。这只能说明存在很多根本不精通 C++ 的程序员。从某种意义上说,你的问题其实可以分成两个小问题。第一个是应该何时使用动态分配(即使用 new 关键字)?第二个问题是应该何时使用指针?

  使用合适的工具通常是做好一项工作的关键。在大部分情况下,存在比使用一般的动态分配或者原指针更合适、更安全的方法。

  动态分配

  在你的问题里,你用了两种方式创建对象。这两种方式主要的不同在于对象的存储时间。当执行 Object myObject;这句代码时,它作为自动变量被创建,这意味着当对象出了作用域时也会自动销毁。而当你使用 new Object ()这种方式时,对象所拥有的内存是动态分配的,这表示直到你调用 delete ()方法对象才会被销毁,否则一直存在。当需要用动态分配内存来处理时,你应该只使用动态分配的方式,也就是说,当你可以使用动态分配内存的时候就不要使用自动变量。

  以下是可能会使用到动态分配的两种常见情况:

  1. 当想让对象在出了作用域后依然存在——且确实就是之前存储在该内存中的对象,而不是对象的拷贝。如果你可以接受使用对象的拷贝或者移动(大部分情况下你应该这样),那么你更应该使用自动存储方式。

  2.  当需要大量内存时,这种情况下极易导致栈溢出。当然如果这对你来说根本不是问题就更好了(大部分情况下这是不可能的)。这显然超出了 C++ 的管辖范围,但是不幸的是,我们必须处理我们开发的系统中存在的这种现实问题。

  当你确实需要使用动态分配时,你应该将它封装到一个智能指针中或者其他能具有 RAII 特性的类型(例如标准容器)。智能指针提供动态分配内存的对象的所有权语义。例如 std::unique_ptr 和 std::shared_ptr。如果你能够合适的使用它,你基本上不需要自己管理内存(参见 Rule of Zero 这篇文章)。

  指针

  事实上,指针除了用来实现动态分配内存外还有很多其它的用法,但是其中大部分也都存在比它们更好的选择。就像前面说过的那样,除非你必须用到指针,否则不要贸然使用。

  需要使用引用的情况:有的时候,你想调用的函数需要访问你当前的对象本身(而不是它的拷贝),那么你就需要使用指针作为参数进行传递(暂不论它是如何分配的)。然而,在大部分情况下,使用引用会比指针更好,这也正是引用被设计的理由。注意一下,这里不需要像上面所说的那样去延长对象的生命周期。前面已经说过了,如果你能接受使用对象的拷贝,那么你就没必要再使用引用了。

  需要使用多态的情况:通常你只能通过对象的指针或者引用来实现多态(也就是根据对象的动态类型来调用函数)。如果这就是你想要的,那么你就需要使用指针或者引用。同样,以指针为优先选择。

  当对象可忽略时,通过传递一个空指针来实现对象是可选的属性:如果它是一个参数的话,你应该优先使用默认参数或者函数重载的方法。否则你应该选择一种可以封装这种行为的类型,例如 boost::optional(或者是 std::optional)。

  当你想降低文件间的编译依存关系从而节省时间:指针的一大特点在于你只需要在前面声明一下指针指向的类型(而如果要使用实际的对象,你还需要定义一下)。这样你就能降低你的编译单元之间的耦合性从而减少编译时间。参考 Pimpl idiom.

  当你想调用C或者类似C风格的函数库的接口时:在这种情况下,你不得不使用指针进行操作。你唯一能做的事情就是要保证你的指针在不使用时要被释放。你也能通过智能指针来操作原指针,例如通过它来调用成员函数。如果被调用库已经为你申请了空间而又希望你通过句柄来释放的话,利用智能指针封装起句柄并利用定制的析构器来释放内存无疑是一种合理的选择。

  翻译: 伯乐在线 - Licorice

  译文链接: http://blog.jobbole.com/62873/

发表评论
用户名: 匿名