我正在阅读c ++ primer plus这本书,我对参考变量和指针感到困惑。 以下是从本书第400页中提取的两段代码。
const free_throws & clone(free_throws & ft)
{
free_throws * pt;
*pt = ft;
return *pt;
}
const free_throws & clone2(free_throws & ft)
{
free_throws newguy;
newguy = ft;
return newguy;
}
这本书说第一个是好的,但第二个是无效的。在函数终止后,即使在函数内声明了指针变量,它仍然存在吗? 另一个问题是为什么我们可以省略第一段代码中的新关键字?如果我们可以创建一个无名结构并为其分配内容,为什么我们需要new关键字? 先感谢您。
对于第一本书,本书提供了几行解释。
The first statement creates a nameless free_throws structure. The pointer pt points to the structure, so *pt is the structure. The code appears to return the structure, but the function declaration indicates that the function really returns a reference to this structure.
答案 0 :(得分:2)
这两个功能都有问题。第一个函数的问题是pt
没有指向有效的free_throws
对象,所以做*pt = ft;
会给你未定义的行为(你正在分配给一个不存在的对象)。第二个函数的问题是你要返回一个局部变量的引用,当函数返回时会被销毁(一个悬空引用)。
在函数终止后,即使在函数内声明了指针变量,它仍然存在吗?
没有。本地声明的指针就像任何其他本地声明的对象一样 - 它将在函数结束时自动销毁。但是,它指向的对象可能具有不同的生命周期。
另一个问题是为什么我们可以在第一段代码中省略新关键字?如果我们可以创建一个无名结构并为其分配内容,为什么我们需要新关键字?
你不能。
如果要创建一个超出函数范围的对象,可以使用new
- 表达式(如new free_throws()
)。这将创建一个具有动态生命周期的对象,您必须稍后使用delete
手动销毁该对象。
要演示,如果您为free_throws
动态分配pt
对象以指向:,那么您的第一个函数将 okay (至少不会调用未定义的行为) p>
const free_throws & clone(free_throws & ft)
{
free_throws * pt = new free_throws();
*pt = ft;
return *pt;
}
然而,它仍然是一个非常糟糕的功能,因为它实际上并不清楚返回的对象需要手动销毁。好的C ++代码将使用智能指针管理动态分配的对象的所有权。至少,您应该使用原始指针,因为C ++开发人员知道要注意它们,并记录您的函数动态分配它返回的对象。
然而,编写一个没有任何动态分配的函数通常要好得多。如果你使用这个clone
函数做到这一点,你会发现它是多么无意义。不妨使用复制构造函数而不是编写额外的函数。