-3

我正在学习 C++,最近我一直在阅读和学习树。我想知道,使用指针有什么好处?

例如,如果我有一个类 Node,并且我有一个名为 Function 的函数,那么有什么区别

  Function (Node *node) 
  Function (Node node)

我知道一个将指针作为参数,而另一个则没有。但我不完全明白有什么区别。

4

5 回答 5

2
Function(Node node)

制作参数的副本。特别是,该函数永远不能修改原始参数,因此如果您在 Function 中操作节点,则调用 Function(node) 的代码将看不到这些更改。

有时你想要这样,这样其他人就不会弄乱你的数据。

对于大型对象,复制数据所需的时间也是不使用指针的缺点。

于 2013-10-15T01:28:35.197 回答
1

Function (Node *node)可以修改node函数定义中的内容。

Function (Node node)不能修改node函数定义中的内容。

于 2013-10-15T01:27:16.950 回答
0

指针是存储另一个变量位置的变量。

所以一个 Node * nodePointer 将有一个类似这样的值:x000000FF,它是虚拟内存中的一个地址。如果您传递此地址,该函数可以修改位于该地址的任何内容,在本例中为您的节点对象。如果传递对象本身,它将是对象的副本,因此方法返回时原始对象将保持不变。

于 2013-10-15T01:40:44.490 回答
0

一般来说在:

Function (Node *node) 
Function (Node node)
  • 第一个允许传递“空”值(=0nullptr
  • 第一个可以修改对象
  • 第二个要求Node有一个复制构造函数
  • sizeof(Node)如果>则第二个效率较低sizeof(Node*)
于 2013-10-15T01:41:27.037 回答
0

首先,您必须了解对象是什么。

House home;

这会在堆栈上为类“House”的实例创建存储,调用构造函数并指定名称“home”以随后引用它。

该对象现在占用堆栈上的空间,但堆栈只是已指定用作堆栈的内存区域。“中央大道”之所以如此命名,是因为它在建造时沿着市中心延伸,今天它只是区分一条道路与另一条道路的一种方式。

当我们谈论按值传递时,例如

int SendGift(House h, Gift g)

这意味着当我们调用这个函数时,我们会创建一个新的、本地的 House 副本,以便调用该函数来操作。

void SendGift(House h, Gift g)
{
    h.porch.insert(g);
    g.setLocation(h);
}

"House h" 和 "Gift g" 都是函数 SendGift 的临时局部变量,所以如果我们这样称呼它:

House home;
Gift gift(Gift::Dollars, 1 * 1000 * 1000);
SendGift(home, gift);

变量“家”没有被触及,礼物也是如此;我们所做的所有更改都是对“g”和“h”的更改,当函数结束时它们就消失了。

该代码的意思是“赠送一百万美元并将其交付给位于 123 Beech Street 的房子”。但是因为我们是按价值传递的,所以它实际上说的是“制作一百万美元的礼物。复制房子和礼物,并将副本放入复制室,然后将它们都销毁。”

它也可能非常昂贵,如果“House”对象有几个 Kb 大,那么每次按值传递时,都必须将大量数据复制到临时对象中。

对于像整数这样的小对象,这不是什么大事(TM)。但是对于像房子这样的大型物体,这太昂贵了。

因此,我们可能希望通过指针传递:

int SendGift(House* h, Gift* g)
{
    h->porch.insert(g);
    g->setLocation(h);
}

指针是包含地址的变量,地址是对象实例在内存中的位置。因此,我们没有将房子一砖一瓦地复制到 SendGift 中的临时文件中,而是传递了地址。所以现在我们的电话

因此,通过指针(或引用)传递有两个主要原因:

  1. 当你想允许一个函数修改它被调用的对象的内容时,
  2. 当您想通过避免创建输入参数的副本来最小化调用函数的成本时。

通常,当意图是 #2 而不是 #1 时,您应该将参数标记为 const。

#include <iostream>

struct BigObj
{
    BigObj() : m_useCount(0) {}

    int m_useCount;
    int m_stuff[4096];
};

void BigObjByValue(BigObj b)
{
    b.m_useCount++;
    std::cout << "BigObjByValue " << (&b) << ". m_useCount is now " << b.m_useCount << std::endl;
}

void BigObjByPtr(BigObj* b)
{
    b->m_useCount++;
    std::cout << "BigObjByValue " << (b) << ". m_useCount is now " << b->m_useCount << std::endl;
}

void BigObjByConstPtr(const BigObj* b)
{
    //b->m_useCount++; // compiler won't allow this, try uncommenting.
    std::cout << "BigObjByValue " << (b) << ". m_useCount is now " << b->m_useCount << std::endl;
}

int main()
{
    BigObj mainB;
    std::cout << "Created mainB at " << (&mainB) << " useCount = " << mainB.m_useCount << std::endl;

    BigObjByValue(mainB);
    std::cout << "in main, m_useCount = " << mainB.m_useCount << std::endl;

    BigObjByPtr(&mainB);
    std::cout << "in main, m_useCount = " << mainB.m_useCount << std::endl;

    BigObjByConstPtr(&mainB);
    std::cout << "in main, m_useCount = " << mainB.m_useCount << std::endl;

    return 0;
}

ideone 现场演示:http: //ideone.com/SjkoNq

于 2013-10-15T05:02:41.580 回答