English 中文(简体)
C++:在哪些场景中,使用指针是一个“好主意”(TM)?[副本]
原标题:C++: What are scenarios where using pointers is a "Good Idea"(TM)? [duplicate]
  • 时间:2010-10-27 04:29:14
  •  标签:
  • c++
  • pointers
This question already has answers here:
Closed 12 years ago.

Possible Duplicate:
Common Uses For Pointers?

我仍在学习C++的基础知识,但我已经知道了足够多的知识来做有用的小程序。

我理解指针的概念,我在教程中看到的例子对我来说很有意义。然而,在实践层面上,作为一名(前)PHP开发人员,我还没有信心在我的程序中真正使用它们。

事实上,到目前为止,我还没有觉得需要使用任何指针。我有自己的类和函数,在不使用任何指针(更不用说指向指针的指针了)的情况下,我似乎做得很好。我忍不住为自己的小程序感到自豪。

尽管如此,我意识到我错过了C++最重要的功能之一,这是一个双刃剑:指针和内存管理可能会造成严重破坏、看似随机的崩溃、难以找到的错误和安全漏洞。。。但同时,正确使用,它们必须允许进行聪明高效的编程

所以:一定要告诉我不使用指针遗漏了什么。

What are good scenarios where using pointers is a must?
What do they allow you to do that you couldn t do otherwise?
In which way to they make your programs more efficient?

指针对指针呢???

[编辑:所有各种答案都很有用。SO的一个问题是,我们不能“接受”不止一个答案。我经常希望我能接受。事实上,正是所有答案的结合有助于更好地理解整个情况。谢谢。]

最佳回答

指针常用于C++中。熟悉它们将有助于您理解更广泛的代码。也就是说,如果你能避免它们,那就太好了,然而,随着程序变得越来越复杂,即使只是为了与其他库接口,你也可能需要它们。

  • 指针主要用于引用动态分配的内存(由new返回)。

  • 它们允许函数接受无法复制到堆栈上的参数,因为这些参数太大或无法复制,例如系统调用返回的对象。(我认为堆叠对齐也可能是一个问题,但过于模糊而无法自信。)

  • 在嵌入式编程中,它们被用来指代硬件寄存器之类的东西,这些寄存器要求代码写入内存中的非常特定的地址。

  • 指针还用于通过它们的基类接口访问对象。也就是说,如果我有一个从类a<code>类B派生的类B:public a{}A*A=&;b对象

  • 使用指针作为数组上的迭代器是一种C语言习惯用法。这可能在较旧的C++代码中仍然很常见,但可能被认为是STL迭代器对象的一个糟糕的表亲。

  • 如果你需要与C码接口,你将不可避免地需要处理用来指动态分配的物体的点码,因为有no参考资料。 Cstrings只是指由Nul 性质终止的一系列特性。

一旦你对指针感到舒服,指针对指针就不会显得那么糟糕了。最明显的例子是main()的参数列表。这通常被声明为<code>char*argv[]</code>,但我看到它被声明为(我相信在法律上)<code>char**argv

声明是C风格,但我说,我有一系列点人可以指.。 这被视为任意的体积(体积由C风格的体体体(由Nul 特性终止的胎体阵列)。

问题回答

当我想给类访问对象的权限,而不给它该对象的所有权时,我会使用指针。即便如此,我也可以使用引用,除非我需要能够更改我正在访问的对象和/或我需要无对象的选项,在这种情况下指针将为NULL。

这个问题以前曾在SO上被问过。我的答案是:

在我编写的C++代码中,我大约每六行使用一次指针。在我的脑海中,以下是最常见的用法:

  • When I need to dynamically create an object whose lifetime exceeds the scope in which it was created.
  • When I need to allocate an object whose size is unknown at compile time.
  • When I need to transfer ownership of an object from one thing to another without actually copying it (like in a linked list/heap/whatever of really big, expensive structs)
  • When I need to refer to the same object from two different places.
  • When I need to slice an array without copying it.
  • When I need to use compiler intrinsics to generate CPU-specific instructions, or work around situations where the compiler emits suboptimal or naive code.
  • When I need to write directly to a specific region of memory (because it has memory-mapped IO).

如果你不觉得需要指点,我不会花很多时间担心它们,直到需要为止。

也就是说,指针有助于更高效编程的主要方式之一是避免实际数据的副本。例如,让我们假设您正在编写一个网络堆栈。您收到一个待处理的以太网数据包。您依次将数据从“原始”以太网驱动程序向上传递到IP驱动程序,再到TCP驱动程序,比如说,HTTP驱动程序,然后再传递到处理其包含的HTML的东西。

如果您为每一个内容制作一个新的副本,那么在您真正开始渲染数据之前,您最终至少制作了四个数据副本。

使用指针可以避免很多这种情况——您只需传递一个指向数据的指针,而不是复制数据本身。网络堆栈的每个连续层都会查看自己的标头,并将一个指针传递给堆栈中的下一个更高层,该指针指向它认为的“有效载荷”。下一层查看自己的标头,修改指针以显示它认为的有效负载,并将其向上传递到堆栈中。所有四个层都使用真实数据的一个副本,而不是四个数据副本。

指针的一个重要用途是动态调整数组大小。当您在编译时不知道数组的大小时,您将需要在运行时分配它。

int *array = new int[dynamicSize];

如果这个问题的解决方案是使用STL中的std::vector,那么它们在后台使用动态内存分配。

有几种情况需要指针:

  • If you are using Abstract Base Classes with virtual methods. You can hold a std::vector and loop through all these objects and call a virtual method. This REQUIRES pointers.
  • You can pass a pointer to a buffer to a method reading from a file etc.
  • You need a lot of memory allocated on the heap.

从一开始就关心记忆问题是件好事。因此,如果你开始使用指针,你不妨看看智能指针,比如boost的shared_ptr。

What are good scenarios where using pointers is a must?
Interviews. Implement strcpy.

What do they allow you to do that you couldn t do otherwise?
Use of inheritance hierarchy. Data structures like Binary trees.

In which way to they make your programs more efficient?
They give more control to the programmer, for creating and deleting resources at run time.

And what about pointers to pointers???
A frequently asked interview question. How will you create two dimensional array on heap.

指针有一个特殊的值,<code>NULL</code>,引用s不会。我在<code>NULL

我只想说,我很少使用指针。我使用引用和stl对象(deque、list、map等)。

一个好主意是当您需要返回一个调用函数应该释放的对象时,或者当您不想按值返回时。

 List<char*>* fileToList(char*filename) { //dont want to pass list by value
 ClassName* DataToMyClass(DbConnectionOrSomeType& data) { 
 //alternatively you can do the below which doesnt require pointers
 void DataToMyClass(DbConnectionOrSomeType& data, ClassName& myClass) { 

这几乎是我唯一使用的情况,但我并没有那么认真地思考。此外,如果我想让一个函数修改一个变量,但不能使用返回值(比如我需要不止一个)

 bool SetToFiveIfPositive(int**v) {

You can use them for linked lists, trees, etc. They re very important data structures.

一般来说,指针很有用,因为它们可以保存内存块的地址。它们在一些低级别驱动程序中特别有用,在这些驱动程序中,它们被有效地用于逐字节地操作一段内存。它们是C++继承自C的最强大的发明。

关于指针对指针,这里有一个“helloworld”示例,向您展示如何使用它。

#include <iostream>

void main()
{
    int i = 1;
    int j = 2;

    int *pInt = &i;                 // "pInt" points to "i"

    std::cout<<*pInt<<std::endl;    // prints: 1

    *pInt = 6;                      // modify i, i = 6

    std::cout<<i<<std::endl;        // prints: 6

    int **ppInt = &pInt;            // "ppInt" points to "pInt"

    std::cout<<**ppInt<<std::endl;  // prints: 6

    **ppInt = 8;                    // modify i, i = 8

    std::cout<<i<<std::endl;        // prints: 8

    *ppInt = &j;                    // now pInt points to j

    *pInt = 10;                     // modify j, j = 10

    std::cout<<j<<std::endl;        // prints: 10
}

正如我们所看到的,“pInt”是一个指向整数的指针,它指向开头的“i”。使用它,您可以修改“i”。“ppInt”是指向“pInt”的指针的指针。使用它,您可以修改恰好是地址的“pInt”。因此,“*ppInt=&;j”使得“pInt”现在指向“j”。所以我们得到了上面所有的结果。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签