|
|
<!-- --- title: OpenFOAM C++ Coding Patterns (tmp/autoPtr) -->
|
|
|
|
|
|
[Back to _coding patterns_](/coding/patterns/patterns)
|
|
|
|
|
|
***We are happy to incorporate content from volunteers!!***
|
|
|
|
|
|
|
|
|
## Coding Patterns
|
|
|
|
|
|
### Handling plain tmp fields
|
|
|
|
|
|
A `tmp` field is a commonly encountered return container. The tmp
|
|
|
`New()` factory method with forwarding makes it more convenient to
|
|
|
handle and avoid repetitve typing. For example,
|
|
|
```
|
|
|
auto tresult = tmp<vectorField>::New(len, Zero);
|
|
|
auto& result = tresult.ref();
|
|
|
|
|
|
// or alternatively
|
|
|
auto tresult(tmp<vectorField>::New(len, Zero));
|
|
|
auto& result = tresult.ref();
|
|
|
|
|
|
...
|
|
|
|
|
|
return tresult;
|
|
|
```
|
|
|
|
|
|
- Since the type is already dictated by the template parameter for the
|
|
|
`New()' method, an `auto` declaration works without issue. When
|
|
|
dereferencing, the choice of variable names (`result` vs `tresult`)
|
|
|
makes the use clear, and makes the code nicely align.
|
|
|
|
|
|
|
|
|
**Anti-pattern**: the older style, which is still very evident in much of
|
|
|
OpenFOAM, but is much more verbose:
|
|
|
```
|
|
|
tmp<vectorField> tresult(new vectorField(len, Zero));
|
|
|
vectorField& result = tresult.ref();
|
|
|
|
|
|
...
|
|
|
return tresult;
|
|
|
```
|
|
|
|
|
|
|
|
|
### NotImplemented
|
|
|
|
|
|
For non-implemented functions returning a `tmp`, we use the C++
|
|
|
`nullptr` which will be automatically converted to an invalid `tmp`
|
|
|
when the code is executed.
|
|
|
```
|
|
|
tmp<vectorField> method
|
|
|
{
|
|
|
NotImplemented;
|
|
|
return nullptr;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
**Anti-pattern**: the older style, which is less prevalent, is to return
|
|
|
an invalid `tmp` or an empty `tmp`. The effect will be the same (since
|
|
|
the code will not be executed), but corresponds to more typing and we
|
|
|
need to match the return types (scalarField, vectorField etc).
|
|
|
```
|
|
|
tmp<vectorField> method
|
|
|
{
|
|
|
NotImplemented;
|
|
|
return tmp<vectorField>();
|
|
|
}
|
|
|
|
|
|
// or
|
|
|
tmp<vectorField> method
|
|
|
{
|
|
|
NotImplemented;
|
|
|
return tmp<vectorField>(new vectorField(0));
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### Return valid, zero-sized tmp field
|
|
|
|
|
|
When a zero-sized tmp field is required:
|
|
|
```
|
|
|
return tmp<vectorField>::New();
|
|
|
```
|
|
|
This uses forwarding to a null-constructed `vectorField`, which has
|
|
|
zero-size.
|
|
|
|
|
|
**Anti-pattern**: manual allocation of the underlying field,
|
|
|
constructing the underlying field explicitly with size 0 instead of
|
|
|
using the null-constructed form (which is defined to be noexcept).
|
|
|
```
|
|
|
return tmp<vectorField>(new vectorField(0));
|
|
|
```
|
|
|
|
|
|
----
|
|
|
|
|
|
Copyright (C) 2019 OpenCFD Ltd. |