Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Variable placement  (Read 1448 times)

0 Members and 1 Guest are viewing this topic.

ineed.help

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Variable placement
« on: June 04, 2014, 10:38:02 am »
Hello.

So, say that you have a class called "Game":
// Game.hpp
class Game
{
private:
        std::fstream fileStream;

        void DoSomething();
};

// Game.cpp
void Game::DoSomething()
{
        fileStream.open("file.txt");
        /* do something... */
        fileStream.close();
}

You're going to call the "DoSomething()" method quite frequently, but with a different file to open each time. Is it better to do as I have above, or should I do it like this?

// Game.hpp
class Game
{
private:
        void DoSomething();
};

// Game.cpp
void Game::DoSomething()
{
        std::fstream fileStream("file.txt");
        /* do something... */
        fileStream.close();
}

... In terms of performance, which is the preferred way of doing things, or do they perform equally?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Variable placement
« Reply #1 on: June 04, 2014, 10:50:09 am »
The second way. In general, declare variables always as late and local as possible. And don't call close(), file streams use RAII. Also, if you're using the stream only to either write or read, but not both, prefer std::ofstream or std::ifstream.

You shouldn't write ugly code because of alleged performance reasons; use a profiler to measure actual problems, and then optimize. Such as in this example, where the expensive operation is the file loading, not the stream object construction.
« Last Edit: June 04, 2014, 10:52:55 am by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

ineed.help

  • Jr. Member
  • **
  • Posts: 56
    • View Profile
Re: Variable placement
« Reply #2 on: June 04, 2014, 11:02:14 am »
If std::fstream's destructor calls <close()> itself, why is <close()> not a private function?

But then how does that work? Does the variable disappear from memory when the function ends? Otherwise, I can't see why it would be beneficial to use it compared to declaring them only once and having them exist until the end of <main()>.

What do you mean by "ugly" code?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Variable placement
« Reply #3 on: June 04, 2014, 11:07:46 am »
If std::fstream's destructor calls <close()> itself, why is <close()> not a private function?
For scenarios where the user wants to close the file before the destruction. The same reason why unique_ptr::reset() or vector::clear() exist, and you hopefully don't call them at end of scope, either...

You should read my article in the first post. If something in C++ forces you to explicitly close or destroy the object, it's badly designed.

But then how does that work? Does the variable disappear from memory when the function ends?
The object is destroyed at the end of scope. Variables are just a way to access objects in your code, they don't exist at runtime. Scopes are absolutely crucial in C++, maybe you should read up on that topic...

What do you mean by "ugly" code?
I mean code that is guided by myths such as "declarations are very inefficient, so I only declare the variable once but with a much wider scope". The priority should be code clarity and correctness, not questionable micro-optimizations.
« Last Edit: June 04, 2014, 11:11:09 am by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Variable placement
« Reply #4 on: June 04, 2014, 11:09:24 am »
Quote
If std::fstream's destructor calls <close()> itself, why is <close()> not a private function?
To leave an option for the user to do error checking if needed. If an error happens in close(), you can catch it if you called it manually, but not if it's triggered from the destructor.

Quote
But then how does that work? Does the variable disappear from memory when the function ends? Otherwise, I can't see why it would be beneficial to use it compared to declaring them only once and having them exist until the end of <main()>.
The variable does not "disappear from memory". It is destructed and the space allocated to it is freed so that it can be reused later for another variable. Local variables are declared on the stack, so in this context, "freed" just means moving a pointer by a few bytes (don't think it is an expensive operation).

The key point here is that construction and destruction of your std::fstream object is absolutely negligible. This shouldn't drive your design / coding decisions. Instead, use the solution that will be the cleanest and easiest to maintain. Since the object is not used outside the function, the cleanest option here is clearly to keep it local to this function.
Laurent Gomila - SFML developer

 

anything