参数定义(类型和名称)和(类型*名称)之间有什么区别?

时间:2009-06-04 06:50:40

标签: c++ argument-passing

这是一个非常基本的问题,但是,从C ++专家那里听到它会很好。

在C ++中有两种相似的方法来声明by-reference参数。

1)使用“星号”:

void DoOne(std::wstring* iData);

2)使用“&”“:

void DoTwo(std::wstring& iData);

每种方法的含义是什么? 在任何情况下都有任何问题吗?

奖金#1:在#1和#2中调用方法的正式方法是什么?它们都被称为“按参考”吗?

奖金#2:故意使用std :: wstring。在每种情况下对标准库类有什么影响?

7 个答案:

答案 0 :(得分:7)

#1使用指针参数('将指针传递给'),#2使用参考参数('通过引用传递')。它们非常相似,但请注意,在这两种情况下,调用代码看起来不同:

std::wstring s;

DoOne(&s); // pass a pointer to s
DoTwo(s); // pass s by reference

有些人更喜欢#1,使用通过指针传递的约定表明该函数可能会改变s的值(即使任一函数都可以)。其他人(包括我自己)更喜欢#2,因为通过引用传递不允许传递NULL。

传递const指针或引用时还有另一个重要区别。临时变量只能传递给const引用参数:

void ByConstPointer(const std::wstring&);
void ByConstReference(const std::wstring*);

void test()
{
  ByConstPointer(&std::wstring(L"Hello")); // error: cannot take address of temporary
  ByConstReference(std::wstring(L"Hello")); // fine
}

答案 1 :(得分:2)

规则编号为1:如果NULL是函数上下文中函数参数的有效值,则将其作为指针传递,否则将其作为参考传递。

基本原理,如果它不能(不应该!)永远为NULL,那么不要让自己完成检查NULL的麻烦。

答案 2 :(得分:1)

在编写示例时,我想出了自己的答案。除了下面以外的任何东西?

每个结果非常相似:对内存中对象的引用最终在方法的范围内。对它们中的任何一个似乎都没有严格的内存要求。该对象可以在堆栈上或堆中。

在堆栈的情况下,每个方法将被调用如下:

{
    std::wstring data;
    DoOne(&data);
    DoTwo(data);
}

然而,当涉及到堆时,第二种方法要求在调用方法之前对象必须存在。如果该对象不存在,则调用者将导致异常,而不是被调用者。

{
    std::wstring* pData = new std::wstring();
    DoOne(pData);
    DoTwo(*pData);
}

在上面,如果发生内存不足的情况且pData结束为NULL,则崩溃将在DoTwo之前发生,但是DoOne会吞下NULL并且可能会在一段时间后崩溃。

答案 3 :(得分:0)

我不会称自己为C ++ gure(除了我的简历),但我会说;除非使用将参数作为指针传递(即函数想要检查null),否则总是使用引用。

这也适用于返回对象的函数,返回指针以某种方式告诉该类的用户它可能为null。

答案 4 :(得分:0)

在DoOne中,可以将iData指定为NULL。如果在调用DoOne后使用它,应用程序将崩溃。

这样的东西
void DoOne(std::wstring* iData)
{
   //Use iData
   delete iData;
   iData = NULL;
}

{
    std::wstring* pData = new std::wstring();
    DoOne(pData);
    pData->someFunction(); //Crash
}

答案 5 :(得分:0)

当你说:

时,你的回答是完全错误的
  

他们每个人的结果都是相当的   类似:对一个对象的引用   记忆最终在方法中   范围。似乎没有严格要求   任何一个的内存要求。

connsider:

void f( int * p1 ) {
   int ** p2 = & p1;
}

这里p1有一个明确的“内存要求” - 它必须存在,我必须能够获取其地址。与此对比

void f( int & r ) }
   int * p = & r;
}

这里r没有自己的存在,它只是一个参考。我接受它 地址我正在考虑r指的东西的地址。

您对NULL指针的评论也是错误的。取消呈现NULL指针会导致未定义的行为 - 这可能会也可能不会导致崩溃。

答案 6 :(得分:0)

如果你编写一个通过指针获取变量的函数,你很可能必须检查指针是否有效(例如,不是NULL),否则你可能会导致程序崩溃。