通过函数初始化指针

时间:2010-06-10 06:01:41

标签: c++ pointers

当我偶然发现这个时,我正在浏览我老师的代码:

Order* order1 = NULL;

然后

order1 = order(customer1, product2);

调用

Order* order(Customer* customer, Product* product)
{
    return new Order(customer, product);
}

这看起来像愚蠢的代码。我不知道为什么,但老师将所有指针初始化为NULL而不是立即声明它们(看完代码完全可能,但他选择不这样做。)

我的问题是:这是好的还是可接受的代码?函数调用是否比明确调用构造函数有任何好处?在这种情况下,新工作如何?我现在能想象代码:

order1 = new Order(customer, product);

6 个答案:

答案 0 :(得分:8)

初始化为空

[edit]因为有一个有效的讨论,我已经改变了选项的顺序,以强调推荐的选项。

变量应声明为本地且尽可能晚,并且立即初始化。因此,最常见的模式是:

Order * order1 = order(...);
在需要order1之前

如果有任何理由将order1的声明与实例化分开,就像这样:

Order * order1;  // Oh no! not initialized!
// ... some code
order1 = order(...);

order1应初始化为NULL,以防止未初始化变量发生的常见错误,在// some code changes时很容易引入。

工厂方法
同样,这里还有一些更改的更改:实例化Order的要求可能会发生变化。我可以想到两种情况:

(1)Order的构造函数无法完成的验证。 Order可能来自第三方库,无法更改,或者实例化需要添加不在Order范围内的验证:

Order* order(Customer* customer, Product* product)             
{      
    // Order can't validate these, since it doesn't "know" the database       
    database.ValidateCustomer(customer); // throws on error
    database.ValidateProduct(product); // throws on error

    return new Order(customer, product);             
}   

(2)您可能需要一个行为不同的订单。

class DemoOrder : public Order  { ... }

Order* order(Customer* customer, Product* product)             
{             
    if (demoMode)
      return new DemoOrder(customer, product); // doesn't write to web service
    else
      return new Order(customer, product);             
}   

然而,我不会盲目地将此作为一般模式。

答案 1 :(得分:3)

在我看来,你的老师是一位老C程序员,并没有完全摆脱他的一些旧习惯。在过去,你必须在函数的开头声明所有变量,所以看到一些旧的计时器仍然这样做并不罕见。

答案 2 :(得分:2)

如果这真的是所有重要的代码,我认为函数或初始NULL值没有任何好处。 new以其始终有效的方式运作。它构造一个Order并返回一个指向它的指针,该指针又由order返回。

答案 3 :(得分:2)

如果在一个函数中发生对NULL的赋值,则代码给出可能很重要,例如构造函数和调用new的赋值发生在另一个函数中。这有三个原因;

  • 如果在调用order = NULL时客户和产品参数可能不可用。
  • 在过渡期间,NULL值可能很重要,让其他函数知道尚未创建订单。
  • 如果Order类占用了大量资源,推迟初始化可能会有所帮助。

最好问问你的老师他们为什么这样做。有时候明显的结论并不正确。

答案 4 :(得分:1)

如果事情真的像你描述的那样,那么你老师的代码就会说明一些相当糟糕的编程实践。

您的问题标记为C ++。在C ++中,适当的技术是将变量声明移动到可以被初始化的位置。即它应该看起来如下

Order* order1 = order(customer1, product2);

同样适用于C99代码,因为C99允许在块的中间声明变量。

在C代码中,声明必须放在块的开头,这可能会导致您无法在声明点有意义地初始化变量。有些人认为在这种情况下你必须使用某些东西初始化变量,任何东西只是为了保持初始化而不是让它未初始化。我可以尊重这个个人喜好,购买个人认为它适得其反。它会干扰编译器的优化,并且可以通过将它们扫地出门来隐藏错误(而不是鼓励正确的修复)。

我会说你老师的C ++代码会受到C带来的一些不良习惯的影响。

答案 5 :(得分:0)

对于给定的代码,没有区别。最好在单个位置使用新创建的对象初始化订单对象。它将避免使用用NULL值初始化的订单变量