EDIT: The same question goes for the constructor and Init().
Edited by simpler, 12 October 2012 - 07:04 AM.
Posted 12 October 2012 - 06:59 AM
Edited by simpler, 12 October 2012 - 07:04 AM.
Posted 12 October 2012 - 07:03 AM
Tristam MacDonald - SDE @ Amazon - swiftcoding [Need to sync your files via the cloud? | Need affordable web hosting?]
Posted 12 October 2012 - 08:43 AM
Posted 12 October 2012 - 08:57 AM
Posted 12 October 2012 - 10:59 AM
Let me rephrase my earlier statement to read: "One should never aim to design code that requires a cleanup function in C++".It also makes sense for reusable objects, especially heavyweight objects that are expensive to create and destroy, but cheap to recycle.
Are fstreams really that heavyweight? Glancing at my local header files it looks like a mutex, a buffer, an underlying stream, and a handful of state variables. It seems to me that the cost of actually locking the mutex, and invoking an open syscall should dominate the construction costs of allocating the buffer.An example of reusable objects would be the C++ file streams. You can use it once by create, open, close, then destroy; or reuse with create, open, close, open, close, open, close, ... etc., then destroy.
Tristam MacDonald - SDE @ Amazon - swiftcoding [Need to sync your files via the cloud? | Need affordable web hosting?]
Posted 12 October 2012 - 11:05 AM
Please reread my post. No, they are not heavyweight. They are reusable.Are fstreams really that heavyweight? Glancing at my local header files it looks like a mutex, a buffer, an underlying stream, and a handful of state variables. It seems to me that the cost of actually locking the mutex, and invoking an open syscall should dominate the construction costs of allocating the buffer.An example of reusable objects would be the C++ file streams. You can use it once by create, open, close, then destroy; or reuse with create, open, close, open, close, open, close, ... etc., then destroy.
Posted 12 October 2012 - 11:35 AM
Sure, they're reusable, but the heavy cost is in the open operation, not the object creation operation (except when the object creation includes the open operation).Please reread my post. No, they are not heavyweight. They are reusable.
Posted 12 October 2012 - 11:39 AM
The point was not about reuse cost.Sure, they're reusable, but the heavy cost is in the open operation, not the object creation operation (except when the object creation includes the open operation).
Please reread my post. No, they are not heavyweight. They are reusable.
Reusing an fstream is like reusing an integer variable: the cost to maintainabilty heavily outweighs the runtime cost savings.
Posted 12 October 2012 - 11:42 AM
And conveniently, (some of) the constructors call open(), and the destructors call close() for you, so actual use can look like: create, destroy, or create, open, destroy, or create, close, open, destroy. Very nice design - very flexible.It also makes sense for reusable objects, especially heavyweight objects that are expensive to create and destroy, but cheap to recycle.
An example of reusable objects would be the C++ file streams. You can use it once by create, open, close, then destroy; or reuse with create, open, close, open, close, open, close, ... etc., then destroy.
MyFile::MyFile()
{
}
MyFile::MyFile(filename)
{
this->Open(filename);
}
My::MyFile(data)
{
this->OpenFromData(data);
}
MyFile::Open(filename)
{
data = ::LoadFileData(filename);
this->OpenFromData(data);
}
MyFile::OpenFromData(data)
{
//actual loading from data...
}
Edited by Servant of the Lord, 12 October 2012 - 11:51 AM.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal
Posted 12 October 2012 - 12:00 PM
And that's precisely the point I am questioning.The point was that sometimes a "reset this object" function is a good thing.
Tristam MacDonald - SDE @ Amazon - swiftcoding [Need to sync your files via the cloud? | Need affordable web hosting?]
Posted 12 October 2012 - 12:35 PM
Posted 12 October 2012 - 01:01 PM
Edited by lride, 12 October 2012 - 01:05 PM.
Posted 12 October 2012 - 01:06 PM
Edited by Daaark, 12 October 2012 - 01:07 PM.
Posted 12 October 2012 - 01:09 PM
I have two issues with this:If you have global objects that requires other objects to be initialized or destroyed before initializing or destroying themselves, init() cleanUp() comes in handy.
Tristam MacDonald - SDE @ Amazon - swiftcoding [Need to sync your files via the cloud? | Need affordable web hosting?]
Posted 12 October 2012 - 04:54 PM
Actually, C++ does guarantee that global variables defined in the same translation unit are constructed in order of definition.[source lang="cpp"]MemoryManager memoryManager; //memoryManager must be initialized before other objectsRenderManager renderManager; //but c++ doesn't guarantee that memoryManager getsAIManager aiManager; //initialized in the order it appears in the source code[/source]
Posted 12 October 2012 - 07:26 PM
Posted 12 October 2012 - 10:05 PM
LSE_CALL CSVectorCrtp() :
m_tLen( 0 ),
m_tAllocated( 0 ),
m_ptData( NULL ) {
}The Reset function:/**
* Reset the list completely. Frees all memory.
*/
LSVOID LSE_CALL Reset() {
for ( LSINT32 I = static_cast<LSINT32>(m_tLen); --I >= 0; ) {
Destroy( static_cast<_tDataType>(I) );
}
m_paDefaultAllocator->Free( m_ptData );
m_ptData = NULL;
m_tLen = m_tAllocated = 0;
}The destructor:LSE_CALL ~CSVectorCrtp() {
Reset();
}/**
* Reset the list without deallocating the whole buffer.
*/
LSVOID LSE_CALL ResetNoDealloc() {
for ( LSINT32 I = static_cast<LSINT32>(m_tLen); --I >= 0; ) {
Destroy( static_cast<_tDataType>(I) );
}
m_tLen = 0;
}While there are ways to control std::vector to achieve the same results, they are fairly non-intuitive. It is a lot easier to just use Reset() and ResetNoDealloc(),which have obvious meanings.Edited by L. Spiro, 13 October 2012 - 06:29 AM.
Posted 12 October 2012 - 10:19 PM