I was browsing my teacher's code when I stumbled across this:
Order* order1 = NULL;
then
order1 = order(customer1, product2);
which calls
Order* order(Customer* customer, Product* product)
{
return new Order(customer, product);
}
This looks like silly code. I'm not sure why, but the teacher initialized all pointers to NULL instead of declaring them right away(looking at the code it's entirely possible, but he chose not to).
My question is: is this good or acceptable code? Does the function call have any benefits over calling a constructor explicitely? And how does new work in this case? Can I imagine the code now as kind of like:
order1 = new Order(customer, product);
You need to initialize a pointer by assigning it a valid address. This is normally done via the address-of operator ( & ). The address-of operator ( & ) operates on a variable, and returns the address of the variable. For example, if number is an int variable, &number returns the address of the variable number .
In C, like normal data pointers (int *, char *, etc), we can have pointers to functions.
The * symbol indicates that the variable is a pointer. To declare a variable as a pointer, you must prefix it with *. In the example above, we have done a pointer declaration and named ptr1 with the data type integer.
Function Pointer Syntaxvoid (*foo)( int ); In this example, foo is a pointer to a function taking one argument, an integer, and that returns void. It's as if you're declaring a function called "*foo", which takes an int and returns void; now, if *foo is a function, then foo must be a pointer to a function.
Init to NULL
[edit] since there's a valid discussion, I've changed the order of the options a bit to emphasize the recommended option.
Variables should be declared as local and as late as possible, and initialized immediately. Thus, the most common pattern is:
Order * order1 = order(...);
just before order1
is required.
If there is any reason to separate the declaration of order1
from the instantiation, like this:
Order * order1; // Oh no! not initialized!
// ... some code
order1 = order(...);
order1
should be initialized to NULL, to prevent common bugs that occur with uninitialized variables, easily introduced when // some code changes
.
Factory method
Again, there's some more change resilence here: the requirements for instantiating an Order
may change. There are two scenarios I can think of right off top of my head:
(1) Validation that can't be done by Order's constructor. Order
may come from a 3rd party library and can't be changed, or instantiation needs to add validation that isn't within the scope of 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) You may need an order that behaves differently.
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);
}
However, I wouldn't make this a general pattern blindly.
It seems to me that your teacher is an old C programmer who hasn't quite shaken off some of his old habits. In the old times, you had to declare all variables at the beginning of a function, so it's not unusual to see some old timers still doing so.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With