class C {
public
T x;
};
Is there an elegant way for the constructor of x to know implicitly in what instance of C it is constructing?
I've implemented such behavior with some dirty inelegant machinery. I need this for my sqlite3 wrapper. I don't like all wrappers I've seen, their API IMO ugly and inconvenient. I want something like this:
class TestRecordset: public Recordset {
public:
// The order of fields declarations specifies column index of the field.
// There is TestRecordset* pointer inside Field class,
// but it goes here indirectly so I don't have to
// re-type all the fields in the constructor initializer list.
Field<__int64> field1;
Field<wstring> field2;
Field<double> field3;
// have TestRecordset* pointer too so only name of parameter is specified
// in TestRecordset constructor
Param<wstring> param;
virtual string get_sql() {
return "SELECT 1, '1', NULL FROM test_table WHERE param=:PARAM";
}
// try & unlock are there because of my dirty tricks.
// I want to get rid of them.
TestRecordset(wstring param_value)
try : Recordset(open_database(L"test.db")), param("PARAM") {
param = param_value;
// I LOVE RAII but i cant use it here.
// Lock is set in Recordset constructor,
// not in TestRecordset constructor.
unlock(this);
fetch();
} catch(...) {
unlock(this);
throw;
}
};
I want to clarify the fact - it is a part of the working code. You can do this in C++. I just want to do it in a more nice way.
I've found a way to get rid of unlock and try block. I've remembered there is such a thing as thread local storage. Now I can write constructor as simple as that:
TestRecordset(wstring param_value):
Recordset(open_database(L"test.db")), param("PARAM") {
param = param_value;
fetch();
}
to dribeas:
My objective is to avoid redundant and tedious typing. Without some tricks behind the scene I will have to type for each Field and Param:
TestRecordset(wstring param_value): Recordset(open_database(L"test.db")), param(this, "PARAM"),
field1(this, 0), field2(this, 1), field3(this, 2) { ... }
It is redundant, ugly and inconvenient. For example, if I'll have to add new field in the
middle of SELECT I'll have to rewrite all the column numbers.
Some notes on your post:
Fields and Params are initialized by their default constructors.
Order of initializers in constructor is irrelevant. Fields are always initialized in order of their declaration. I've used this fact to track down column index for fields
Base classes are constructed first. So when Fields are constructed internal field list in Recordset are ready to use by Filed default constructor.
I CAN'T use RAII here. I need to acquire lock in Recorset constructor and release it obligatory in TestRecordset constructor after all Fields are constructed.
No. Objects aren't supposed to need to know where they're being used from in order to work. As far as x is concerned, it's an instance of T. That's it. It doesn't behave differently according to whether it's a member of class C, a member of class D, an automatic, a temporary, etc.
Furthermore, even if the T constructor did know about the instance of C, that instance of C would be incomplete since of course it has not finished construction yet, because its members haven't been constructed. C++ offers you plenty of chances to shoot yourself in the foot, but offering you a reference to an incomplete object in another class's constructor isn't one of them.
The only thing I can think of to approximate your code example is to do something like
#define INIT_FIELDS field1(this), field2(this), field3(this)
immediately after the list of fields, then use INIT_FIELDS in the initializer list and #undef it. It's still duplication, but at least it's all in one place. This will probably surprise your colleagues, however.
The other way to make sure you don't forget a field is to remove the zero-arg constructor from Field. Again, you still have to do the typing, but at least if you forget something the compiler will catch it. The non-DRY nature of initializer lists is, I think, something C++ just has to live with.
Adding on to One by One's answer, the actual question you should be asking is: "what is wrong with my solution design that it requires objects to know where they are instanciated?"
I don't think so.
Out of pure curiosity, why should it matter ? do you have a context in which this can be useful?
M.
I experiment with things like this in C# all the time - I use reflection to do it.
Consider getting a reflection or code generation library for C++ to help you do what you want to.
Now, I can't tell you how to find a good reflection or code generation library for C++, but that's a different question!
I am interested in your code. You comment that all fields plus the param attribute have pointers back into the TestRecordSet but that they don't need to be initialized? Or is it the object of the question, how to avoid having to pass the this pointers during construction?
If what you want is avoid adding all fields in the initialization list of your constructor, then it is a flawed objective. You should always initialize all your members in the initialization list and do so in the same order that they are declared in the class (this is not language enforced, but more of a globally learnt experience).
Your use of the try constructor block is just about he only recommended usage for that functionality (Anyone interested read GOTW#66) if it is indeed required. If the RecordSet member has been constructed (and thus the lock acquired) and something goes wrong afterwards in the constructor then [see quote below] the RecordSet will be destroyed and if it uses RAII internally it will free the lock, so I believe that the try/catch may not really be required.
C++03, 15.2 Exception Handling / Constructors and destructors
An object that is partially
constructed or partially destroyed
will have destructors executed for all
of its fully constructed subobjects,
that is, for subobjects for which the
constructor has completed execution
and the destructor has not yet begun
execution.
Related
Lets say I have a class encapsulating one (or multiple) member(s) which must in some way be initialized and there is no reasonable way to use the class without it (so I don't want to make it optional).
Is it then better to have initialization run in its constructor like so:
class MyClass
{
MyClass()
{
if(!obj.initialize()
throw ...;
}
private:
MyObject obj;
}
or would you suggest the following design:
class MyClass
{
MyClass()
{
}
bool initialize()
{
return obj.initialize();
}
private:
MyObject obj;
}
The 1st one looks appealing because I can guarantee all requirements for using my class have been met after the constructor has run and I can report any errors by throwing an exception.
The 2nd looks good because it doesn't overload constructors with stuff that intuitively doesn't belong there, especially once the initialization routine gets complex and i.e. creates widgets, opens database connections, initializes 3rd party libraries etc. In a lot of legacy code I'm working with, ctors are flooded with parameters and intialization stuff, probably running thousands of code lines before this type of bloated object construction is even done. Trying to refactor these into something cleaner is really hard at some point because there are too many dependencies involved. That's what motivated my question.
The big disadvantage of design #2 I can see is that I need a public initialization routine which the client must remember to call. But since this can and probably will be forgotten, I have to track and check intialization state in all public members and somehow treat errors (probably an assert will do). This will also clutter my class with stuff that's not there if I chose design #1.
So what's my best choice here?
"The 1st one looks appealing because I can guarantee all requirements for using my class have been met after the constructor has run ...."
This must be the case otherwise the design is bad.
When the constructor completes then the object must be usable without any undefined behaviour and according to its interface specification.
BUT that does not mean the object needs to be configured for a given purpose.
I like to separate out initialization from configuration.
For example look at std::fstream. You can create a completely initialized fstream object without opening any files:
std::fstream fs; // initialized but not configured
It does not exhibit undefined behaviour and will operate according to its interface specification.
So you can use its interface to configure it to a given purpose - for example to read a specific file:
fs.open("myfile.txt", std::ios::in); // configured
The default constructor should do the absolute minimum to put the object into working order without, necessarily configuring it to a given task.
That being said there is no reason not to have other constructors to make creating configured objects easier:
std::fstream fs("myfile.txt", std::ios::in); // initialized & configured
Move the code from MyObject::initialize to MyObject's constructor (the throw as well, if necessary). Now the implicitly-defined default constructor for MyClass will do the right job.
I'm working on a class that acts as a scope helper for reference-counted objects. The interface should allow to use the class as follows:
{
Handle<String> s = Handle<String>::New("Hello, World!");
s = s->Concat(Handle<String>::New(" My name is Peter"));
}
while String is the class that contains the reference-count.
I am not very familar with move semantics and I was unable to find a concrete paper which sates the conditions that apply for move-semantics. Basically, what I am wondering about is:
Can this be an object that was already initialized in the move-constructor? Because if that is the case, i can't tell apart if the member in my Handle class that points to the String contains some garbage value or is actually pointing to a real String.
I guess it's possible using placement construction, but doing so is asking for trouble. I don't even know why I mentioned it. Short answer: No, it cannot. Move constructors only differ from other constructors in the type of values they accept.
Whenever an object is constructed, should the constructor always leave it in an "initialised" state?
For example, if an Image class has two constructors where one takes a file path string, and the other takes no parameters, is it bad practice for the latter to leave the image object in an invalid state?
Assuming the class is written to handle both states.
I ask this because I find it almost necessary to have a default construct in a lot of cases. Especially when an object is a member of a class and you want to initialise it IN the constructor of that class.
EDIT: I am aware of the member initialiser list. I have found a few situations where I would like to construct the object DURING the constructor of the class it is held in, not before. Although, I understand that this could potentially be more dangerous than any other alternative.
It all boils down to the definition of a "valid state": if the methods of your class handle the state when the path is empty, then the state with the empty path is a valid state, and is definitely acceptable.
This may not be optimal from the coding perspective, though, because potentially you might need to add multiple checks for the path to be valid. You can often manage complexity by implementing the State Pattern.
I find it almost necessary to have a default construct in a lot of cases. Especially when an object is a member of a class and you want to initialise it IN the constructor of that class.
You do not need a default constructor in order to initialize an object in the constructor of the class of which it is a member, as long as you construct the dependent in the initialization list.
Your last line:
I ask this because I find it almost necessary to have a default construct in a lot of cases. Especially when an object is a member of a class and you want to initialise it IN the constructor of that class.
Implies that you are not using member initializer lists. You do not need a default constructor in this case. Example:
class Member {
public:
Member(std::string str) { std::cout << str << std::endl; }
};
class Foo {
public:
Foo() : member_("Foo") {}
private:
Member member_;
}
Additionally, your question title and body conflict and the terminology is a bit vague. When constructing, it is usually best to leave the object in a valid and usable state. Sometimes the second aspect (being usable) is less necessary, and many solutions require it. Further, in C++11, moving from an object must leave it in a valid state, but doesn't necessarily (and in many cases shouldn't) leave it in a usable state.
EDIT: To address your concern about doing work in your constructor, consider moving the work to either a static member of the Member class, or a private (static or non-static) function in the owning class:
class Member {
public:
Member(std::string str) { std::cout << str << std::endl; }
};
class Foo {
public:
Foo() : member_(CreateFoo()) {}
private:
Member CreateMember() {
std::string str;
std::cin >> str;
return Member(str);
}
Member member_;
};
One danger of this approach, however, is that the intialization order can be important if you use a non-static member function to do the creation. A static function is much much safer, but you may wish to pass some other pertinent member info. Remember that initialization is done in order of member declaration within the class, NOT initializer list declaration order.
Yes, it should always be valid. However, it is usually not very well defined what makes the object valid. At the very least, the object should be usable in a way without crashing. This, however, does not mean that all operations can be performed on the object, but there should be at least one. In many cases, that's just assignment from another source (e.g. std container iterators) and destruction (this one is mandatory, even after a move). But there more operations the objects supports in any kind of state, the less prone to error it will be.
It is usually a trade-off. If you can get away with objects only having states where all operations are valid, that's certainly great. However, those cases are rare, and if you have to jump through hoops to get there, it's usually easier to just add and document preconditions to some of its functionality. In some cases, you might even split the interface to differentiate between functions that make this trade-off and those that do not. A popular example of this is in std::vector, where you need to have enough elements as a precondition to using operator[]. On the other hand, the at() function will still work, but throw an exception.
First, let us define what exactly a "valid state" is: Its an state where the object could do its work.
For example, if we are writting a class that manages a file and let us to write and read the file, a valid state (following our definition) could be an state where the object is holding a correctly oppened file and its ready to read/write on it.
But consider other situation: Whats the state of a moved rvalue?
File::File( File&& other )
{
_file_handle = other._file_handle;
other._file_handle = nullptr; //Whats this state?
}
Its a state where the file object its not ready to write/read on a file, but is ready to be initialized. That is, is a ready to initialize state.
Now consider an alternative implementation of the above ctor using the copy and swap idiom:
File::File() :
_file_handle{ nullptr }
{}
File::File( File&& other ) : File() //Set the object to a ready to initialice state
{
using std::swap; //Enable ADL
swap( *this , other );
}
Here we use the default ctor to put the object on a ready to initialice state, and just swap the passed rvalue with this object, resulting on exactly the same behaviour as the first implementation.
As we have seen above, one thing is a ready to work state, a state where the object is ready to do whats supposed to do, and other completely different thing is a ready to initialize state: A state where the object is not ready to work, but is ready to be initialized and setted up to work..
My answer to your question is: An object is not alwways in a valid state (Its not allways ready to be used), but if its not ready to be used it should be ready to be initialized and then ready to work.
Normally, yes. I've seen a few good counterexamples but they are so rare.
Move semantics are great for RAII classes. They allow one to program as if one had value semantics without the cost of heavy copies. A great example of this is returning std::vector from a function. Programming with value semantics however means, that one would expect types to behave like primitive data types. Those two aspects sometimes seem to be at odds.
On the one hand, in RAII one would expect the default constructor to return a fully initialized object or throw an exception if the resource acquisition failed. This guarantees that any constructed object will be in a valid and consistent state (i.e. safe to use).
On the other hand, with move semantics there exists a point when objects are in a valid but unspecified state. Similarly, primitive data types can be in an uninitialized state. Therefore, with value semantics, I would expect the default constructor to create an object in this valid but unspecified state, so that the following code would have the expected behavior:
// Primitive Data Type, Value Semantics
int i;
i = 5;
// RAII Class, Move Semantics
Resource r;
r = Resource{/*...*/}
In both cases, I would expect the "heavy" initialization to occur only once. I am wondering, what is the best practice regarding this? Obviously, there is a slight practical issue with the second approach: If the default constructor creates objects in the unspecified state, how would one write a constructor that does acquire a resource, but takes no additional parameters? (Tag dispatching comes to mind...)
Edit: Some of the answers have questioned the rationale of trying to make your classes work like primitive data types. Some of my motivation comes from Alexander Stepanov's Efficient Programming with Components, where he talks about regular types. In particular, let me quote:
Whatever is a natural idiomatic expression in c [for built-in types], should be a natural idiomatic expression for regular types.
He goes on to provide almost the same example as above. Is his point not valid in this context? Am I understanding it wrong?
Edit: As there hasn't been much discussion, I am about to accept the highest voted answer. Initializing objects in a "moved-from like" state in the default constructor is probably not a good idea, since everyone who agreed with the existing answers would not expect that behavior.
Programming with value semantics however means, that one would expect
types to behave like primitive data types.
Keyword "like". Not "identically to".
Therefore, with value semantics, I would expect the default
constructor to create an object in this valid but unspecified state
I really don't see why you should expect that. It doesn't seem like a very desirable feature to me.
what is the best practice regarding this?
Forget this idea that a non POD class should share this feature in common with primitive data types. It's wrong headed. If there is no sensible way to initialize a class without parameters, then that class should not have a default constructor.
If you want to declare an object, but hold off on initializing it (perhaps in a deeper scope), then use std::unique_ptr.
If you accept that objects should generally be valid by construction, and all possible operations on an object should move it only between valid states, then it seems to me that by having a default constructor, you are only saying one of two things:
This value is a container, or another object with a reasonable “empty” state, which I intend to mutate—e.g., std::vector.
This value does not have any member variables, and is used primarily for its type—e.g., std::less.
It doesn’t follow that a moved-from object need necessarily have the same state as a default-constructed one. For example, an std::string containing the empty string "" might have a different state than a moved-from string instance. When you default-construct an object, you expect to work with it; when you move from an object, the vast majority of the time you simply destroy it.
How would one write a constructor that does acquire a resource, but takes no additional parameters?
If your default constructor is expensive and takes no parameters, I would question why. Should it really be doing something so expensive? Where are its default parameters coming from—some global configuration? Maybe passing them explicitly would be easier to maintain. Take the example of std::ifstream: with a parameter, its constructor opens a file; without, you use the open() member function.
What you can do is lazy initialization: have a flag (or a nulled pointer) in your object that indicates whether the object is fully initialized. Then have a member function that uses this flag to ensure initialization after it is run. All your default constructor needs to do is to set the initialization flag to false. If all members that need an initialized state call ensure_initialization() before starting their work, you have perfect semantics and no double heavy initialization.
Example:
class Foo {
public:
Foo() : isInitialized(false) { };
void ensureInitialization() {
if(isInitialized) return;
//the usual default constructor code
isInitialized = true;
};
void bar() {
ensureInitialization();
//the rest of the bar() implementation
};
private:
bool isInitialized;
//some heavy variables
}
Edit:
To reduce the overhead produced by the function call, you can do something like this:
//In the .h file:
class Foo {
public:
Foo() : isInitialized(false) { };
void bar();
private:
void initialize();
bool isInitialized;
//some heavy variables
}
//In the .cpp file:
#define ENSURE_INITIALIZATION() do { \
if(!isInitialized) initialize(); \
} while(0)
void Foo::bar() {
ENSURE_INITIALIZATION();
//the rest of the bar() implementation
}
void Foo::initialize() {
//the usual default constructor code
isInitialized = true;
}
This makes sure that the decision to initialize or not is inlined without inlining the initialization itself. The later would just bloat the executable and reduce instruction cache efficiency, but the first can't be done automatically, so you need to employ the preprocessor for that. The overhead of this approach should be less than a function call on average.
I'm currently having a discussion with my teacher about class design and we came to the point of Initialize() functions, which he heavily promotes. Example:
class Foo{
public:
Foo()
{ // acquire light-weight resources only / default initialize
}
virtual void Initialize()
{ // do allocation, acquire heavy-weight resources, load data from disk
}
// optionally provide a Destroy() function
// virtual void Destroy(){ /*...*/ }
};
Everything with optional parameters of course.
Now, he also puts emphasis on extendability and usage in class hierarchies (he's a game developer and his company sells a game engine), with the following arguments (taken verbatim, only translated):
Arguments against constructors:
can't be overridden by derived classes
can't call virtual functions
Arguments for Initialize() functions:
derived class can completely replace initialization code
derived class can do the base class initialization at any time during its own initialization
I have always been taught to do the real initialization directly in the constructor and to not provide such Initialize() functions. That said, I for sure don't have as much experience as he does when it comes to deploying a library / engine, so I thought I'd ask at good ol' SO.
So, what exactly are the arguments for and against such Initialize() functions? Does it depend on the environment where it should be used? If yes, please provide reasonings for library / engine developers or, if you can, even game developer in general.
Edit: I should have mentioned, that such classes will be used as member variables in other classes only, as anything else wouldn't make sense for them. Sorry.
For Initialize: exactly what your teacher says, but in well-designed code you'll probably never need it.
Against: non-standard, may defeat the purpose of a constructor if used spuriously. More importantly: client needs to remember to call Initialize. So, either instances will be in an inconsistent state upon construction, or they need lots of extra bookkeeping to prevent client code from calling anything else:
void Foo::im_a_method()
{
if (!fully_initialized)
throw Unitialized("Foo::im_a_method called before Initialize");
// do actual work
}
The only way to prevent this kind of code is to start using factory functions. So, if you use Initialize in every class, you'll need a factory for every hierarchy.
In other words: don't do this if it's not necessary; always check if the code can be redesigned in terms of standard constructs. And certainly don't add a public Destroy member, that's the destructor's task. Destructors can (and in inheritance situations, must) be virtual anyway.
I"m against 'double initialization' in C++ whatsoever.
Arguments against constructors:
can't be overridden by derived classes
can't call virtual functions
If you have to write such code, it means your design is wrong (e.g. MFC). Design your base class so all the necessary information that can be overridden is passed through the parameters of its constructor, so the derived class can override it like this:
Derived::Derived() : Base(GetSomeParameter())
{
}
This is a terrible, terrible idea. Ask yourself- what's the point of the constructor if you just have to call Initialize() later? If the derived class wants to override the base class, then don't derive.
When the constructor finishes, it should make sense to use the object. If it doesn't, you've done it wrong.
One argument for preferring initialization in the constructor: it makes it easier to ensure that every object has a valid state. Using two-phase initialization, there's a window where the object is ill-formed.
One argument against using the constructor is that the only way of signalling a problem is through throwing an exception; there's no ability to return anything from a constructor.
Another plus for a separate initialization function is that it makes it easier to support multiple constructors with different parameter lists.
As with everything this is really a design decision that should be made with the specific requirements of the problem at hand, rather than making a blanket generalization.
A voice of dissension is in order here.
You might be working in an environment where you have no choice but to separate construction and initialization. Welcome to my world. Don't tell me to find a different environment; I have no choice. The preferred embodiment of the products I create is not in my hands.
Tell me how to initialize some aspects of object B with respect to object C, other aspects with respect to object A; some aspects of object C with respect to object B, other aspects with respect to object A. The next time around the situation may well be reversed. I won't even get into how to initialize object A. The apparently circular initialization dependencies can be resolved, but not by the constructors.
Similar concerns goes for destruction versus shutdown. The object may need to live past shutdown, it may need to be reused for Monte Carlo purposes, and it might need to be restarted from a checkpoint dumped three months ago. Putting all of the deallocation code directly in the destructor is a very bad idea because it leaks.
Forget about the Initialize() function - that is the job of the constructor.
When an object is created, if the construction passed successfully (no exception thrown), the object should be fully initialized.
While I agree with the downsides of doing initialization exclusively in the constructor, I do think that those are actually signs of bad design.
A deriving class should not need to override base class initialization behaviour entirely. This is a design flaw which should be cured, rather than introducing Initialize()-functions as a workaround.
Not calling Initialize may be easy to do accidentally and won't give you a properly constructed object. It also doesn't follow the RAII principle since there are separate steps in constructing/destructing the object: What happens if Initialize fails (how do you deal with the invalid object)?
By forcing default initialization you may end up doing more work than doing initialization in the constructor proper.
Ignoring the RAII implications, which others have adequately covered, a virtual initialization method greatly complicates your design. You can't have any private data, because for the ability to override the initialization routine to be at all useful, the derived object needs access to it. So now the class's invariants are required to be maintained not only by the class, but by every class that inherits from it. Avoiding that sort of burden is part of the point behind inheritance in the first place, and the reason constructors work the way they do with regard to subobject creation.
Others have argued at length against the use of Initialize, I myself see one use: laziness.
For example:
File file("/tmp/xxx");
foo(file);
Now, if foo never uses file (after all), then it's completely unnecessary to try and read it (and would indeed be a waste of resources).
In this situation, I support Lazy Initialization, however it should not rely on the client calling the function, but rather each member function should check if it is necessary to initialize or not. In this example name() does not require it, but encoding() does.
Only use initialize function if you don't have the data available at point of creation.
For example, you're dynamically building a model of data, and the data that determines the object hierarchy must be consumed before the data that describes object parameters.
If you use it, then you should make the constructor private and use factory methods instead that call the initialize() method for you. For example:
class MyClass
{
public:
static std::unique_ptr<MyClass> Create()
{
std::unique_ptr<MyClass> result(new MyClass);
result->initialize();
return result;
}
private:
MyClass();
void initialize();
};
That said, initializer methods are not very elegant, but they can be useful for the exact reasons your teacher said. I would not consider them 'wrong' per se. If your design is good then you probably will never need them. However, real-life code sometimes forces you to make compromises.
Some members simply must have values at construction (e.g. references, const values, objects designed for RAII without default constructors)... they can't be constructed in the initialise() function, and some can't be reassigned then.
So, in general it's not a choice of constructor vs. initialise(), it's a question of whether you'll end up having code split between the two.
Of bases and members that could be initialised later, for the derived class to do it implies they're not private; if you go so far as to make bases/members non-private for the sake of delaying initialisaton you break encapsulation - one of the core principles of OOP. Breaking encapsulation prevents base class developer(s) from reasoning about the invariants the class should protect; they can't develop their code without risking breaking derived classes - which they might not have visibility into.
Other times it's possible but sometimes inefficient if you must default construct a base or member with a value you'll never use, then assign it a different value soon after. The optimiser may help - particularly if both functions are inlined and called in quick succession - but may not.
[constructors] can't be overridden by derived classes
...so you can actually rely on them doing what the base class needs...
[constructors] can't call virtual functions
The CRTP allows derived classes to inject functionality - that's typically a better option than a separate initialise() routine, being faster.
Arguments for Initialize() functions:
derived class can completely replace initialization code
I'd say that's an argument against, as above.
derived class can do the base class initialization at any time during its own initialization
That's flexible but risky - if the base class isn't initialised the derived class could easily end up (due to oversight during the evolution of the code) calling something that relies on that base being initialised and consequently fails at run time.
More generally, there's the question of reliable invocation, usage and error handling. With initialise, client code has to remember to call it with failures evident at runtime not compile time. Issues may be reported using return types instead of exceptions or state, which can sometimes be better.
If initialise() needs to be called to set say a pointer to nullptr or a value safe for the destructor to delete, but some other data member or code throws first, all hell breaks loose.
initialise() also forces the entire class to be non-const in the client code, even if the client just wants to create an initial state and ensure it won't be further modified - basically you've thrown const-correctness out the window.
Code doing things like p_x = new X(values, for, initialisation);, f(X(values, for initialisation), v.push_back(X(values, for initialisation)) won't be possible - forcing verbose and clumsy alternatives.
If a destroy() function is also used, many of the above problems are exacerbated.