当我偶然发现这个时,我正在浏览我老师的代码:
Order* order1 = NULL;
然后
order1 = order(customer1, product2);
调用
Order* order(Customer* customer, Product* product)
{
return new Order(customer, product);
}
这看起来像愚蠢的代码。我不知道为什么,但老师将所有指针初始化为NULL而不是立即声明它们(看完代码完全可能,但他选择不这样做。)
我的问题是:这是好的还是可接受的代码?函数调用是否比明确调用构造函数有任何好处?在这种情况下,新工作如何?我现在能想象代码:
order1 = new Order(customer, product);
答案 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
时客户和产品参数可能不可用。最好问问你的老师他们为什么这样做。有时候明显的结论并不正确。
答案 4 :(得分:1)
如果事情真的像你描述的那样,那么你老师的代码就会说明一些相当糟糕的编程实践。
您的问题标记为C ++。在C ++中,适当的技术是将变量声明移动到可以被初始化的位置。即它应该看起来如下
Order* order1 = order(customer1, product2);
同样适用于C99代码,因为C99允许在块的中间声明变量。
在C代码中,声明必须放在块的开头,这可能会导致您无法在声明点有意义地初始化变量。有些人认为在这种情况下你必须使用某些东西初始化变量,任何东西只是为了保持初始化而不是让它未初始化。我可以尊重这个个人喜好,购买个人认为它适得其反。它会干扰编译器的优化,并且可以通过将它们扫地出门来隐藏错误(而不是鼓励正确的修复)。
我会说你老师的C ++代码会受到C带来的一些不良习惯的影响。
答案 5 :(得分:0)
对于给定的代码,没有区别。最好在单个位置使用新创建的对象初始化订单对象。它将避免使用用NULL值初始化的订单变量