我正在学习 C++,最近我一直在阅读和学习树。我想知道,使用指针有什么好处?
例如,如果我有一个类 Node,并且我有一个名为 Function 的函数,那么有什么区别
Function (Node *node)
Function (Node node)
我知道一个将指针作为参数,而另一个则没有。但我不完全明白有什么区别。
Function(Node node)
制作参数的副本。特别是,该函数永远不能修改原始参数,因此如果您在 Function 中操作节点,则调用 Function(node) 的代码将看不到这些更改。
有时你想要这样,这样其他人就不会弄乱你的数据。
对于大型对象,复制数据所需的时间也是不使用指针的缺点。
Function (Node *node)
您可以修改node
函数定义中的内容。
Function (Node node)
您不能修改node
函数定义中的内容。
指针是存储另一个变量位置的变量。
所以一个 Node * nodePointer 将有一个类似这样的值:x000000FF,它是虚拟内存中的一个地址。如果您传递此地址,该函数可以修改位于该地址的任何内容,在本例中为您的节点对象。如果传递对象本身,它将是对象的副本,因此方法返回时原始对象将保持不变。
一般来说在:
Function (Node *node)
Function (Node node)
0
或nullptr
)Node
有一个复制构造函数sizeof(Node)
如果>则第二个效率较低sizeof(Node*)
首先,您必须了解对象是什么。
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 中的临时文件中,而是传递了地址。所以现在我们的电话
因此,通过指针(或引用)传递有两个主要原因:
通常,当意图是 #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