?
Solved

making ifstream available to other functions

Posted on 2001-08-30
17
Medium Priority
?
472 Views
Last Modified: 2008-06-16
if i start reading a file using ifstream in a function, but want to split the file read over several functions to make it easier, how do i access my ifstream from another function?
do i have to pass it to the next function, or can i put it in my class and have it available to all member functions?
any help would be appreciated
0
Comment
Question by:MitchBroadhead
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 3
  • +4
17 Comments
 
LVL 6

Expert Comment

by:Triskelion
ID: 6440777
Can you pass a pointer to it into the other functions?
0
 
LVL 1

Author Comment

by:MitchBroadhead
ID: 6440789
how?
i would prefer to make it globally available, if possible
0
 
LVL 3

Expert Comment

by:jtm111
ID: 6440837
I agree, pass a pointer to the ifstream. But make sure the file is both opened and closed within the same function. Just like memory allocation - don't allocate in one function and delete in another.

read_file()
{

  ifstream in("filename"); // open

  send_to_function_to_read_some(&in);
  send_to_other_function_to_read_some(&in);
 
  in.close();

}

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Expert Comment

by:AssafLavie
ID: 6440878
There's actually no need to use pointer - you can use references.

void foo(ifstream& f);
main
{
ifstream f1;
... //process
foo(f);
};

You should only pass around pointers when it is logical to pass a NULL value. In this case it's not and references will do. There are also no ownership issues with this code since it's all happening synchronously, so IMO pointers aren't needed at all.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6440894
Can you post some of your code?
0
 
LVL 6

Expert Comment

by:Triskelion
ID: 6440926
Pointer / Reference
Same general concept.
0
 
LVL 4

Expert Comment

by:jtwine100697
ID: 6441205
> i would prefer to make it globally available, if possible

You can create a global pointer and then set it at the time the ifstream is constructed.  Something similar to:

//
// At Global Scope...
//
ifstream *g_pMyIfStream = NULL; // Global Pointer

//
// Where ifstream Object Is Created...
//
static std::ifstream s_MyIfStream(...);
g_pMyIfStream = &s_MyIfStream;

//
// Or If Both The Object And Pointer Are At Global Scope (The Pointer Could Be Eliminated In This Case):
//
ifstream g_ifsMyIfStream; // Global Object
ifstream *g_pMyIfStream = *g_ifsMyIfStream; // Global Pointer

(That might run you into issues with when and how global objects are instantiated and/or initialized.)

The problem with the global pointer is that you need to have it pointing to an object that will not go out of scope for the duration of the use of the pointer.  You can create the object at global scope, initialize it in code, and then use a pointer to it, for example.

References need to be initialized when created, so you would have to have either the target object already in existance (at global scope, for example), or initialize it with a temporary object (not a great idea).

-=- James.
0
 
LVL 3

Expert Comment

by:jtm111
ID: 6441788
On containing ownership of file handling in one function: true the file read occurs synchronously but I'm thinking of the poor maintenance programmer.
0
 
LVL 2

Expert Comment

by:smitty1276
ID: 6441868
There's no need to use pointers or references at all if it is, as you say, used in a class.  Just make it a protected or private member of the class and all of your class's member functions will already have access to it.
0
 
LVL 4

Expert Comment

by:jtwine100697
ID: 6441896
> > Just like memory allocation - don't allocate in one function and delete in another.

Sorry, but that does not make sense to me: many non-trivial applications allocate resources (memory included) in one place and free them in another.  COM methods that handle BSTRs require this functionality in some instances (because you are "handing-off" ownership of the BSTR to the method).

You may want to do the same with a file handle.  For example, for logging.  It takes a decent amount of time to keep opening and closing the log file, when it would be faster to open it on startup, and close it on shutdown.

-=- James.

0
 
LVL 4

Expert Comment

by:AssafLavie
ID: 6443762
>> You can create a global pointer and then set it at the
>> time the ifstream is constructed.  Something
>> similar to:
>> //
>> // At Global Scope...
>> //
>> ifstream *g_pMyIfStream = NULL; // Global Pointer

A more appropriate solution, IMO, would be to use an initialization function. This way you can return a reference - not a pointer + you can control the order of initialization of these pseudo global variables across compilation units (something that you cannot do with regular globals). Plus, it give you another level of abstraction which is a good thing, especially when it comes with no cost.

so use this:
ifstream& GlobalStream()
{
    static ifstream d;
    return f;
}

instead of simple globals whenever you can. It's a good guideline. (I believe it's from Effective C++)

>> References need to be initialized when created, so you
>> would have to have either the target object already
>> in existance (at global scope, for example), or
>> initialize it with a temporary object (not a great idea).
That's not accurate, given the fact that you can use initialization functions to return references.
0
 
LVL 2

Expert Comment

by:smitty1276
ID: 6443982
Just do like you said in the question and make it a protected or private member of the class.
--------------------------------------------------
class myClass
{
private:
  ofstream out;
public:
  myClass( char *outFile )
       { out.open(outFile); }
  ~myClass()
       { out.close();      }

  void WriteToFile( char *toWrite );
}

void myClass::WriteToFile( char *toWrite )
{
  out << toWrite;
}
--------------------------------------------------

All of your member functions can use it without any references or pointers.
   

0
 
LVL 1

Author Comment

by:MitchBroadhead
ID: 6444378
smitty
that is exactly what i mean.  here is some of my code.  i am using a struct instead of a class, but i don't suppose it make much difference.
i want functions ReadFile(), CalculateSmoothNormals(), CalculateNormals() to be able to use ifstream input(strFilename);, called from ReadFile().
If there is any performance increase in passing the pointer (as it is only 3 functions), then someone can show that method too!


//*************************************
//*************************************
//DXF Structure
//*************************************
//*************************************

struct Coordinate3D_dbl
{
     double x;
     double y;
     double z;
}

struct Coordinate3D_sng
{
     float x;
     float y;
     float z;
}

//Store header things, like min,max extents
struct DXF_Header
{
     char strComment[100];
}

//stores the drawing object
//1 side for a point, 2 sides for a line, 3 for a triangle and so on
//The VertexIndices relate to DXFEntities.Vertices(n)
struct TDPolygons
{
     char NSides;
     int Colour;
     int Layer;
     long int VertexIndices[4];
}

//Store the number of entities, the entities as TDPolygons, the raw coordinates
struct DXFEntities
{
  long int NPolygons;
  TDPolygons MyPolygons[20000];
  long int NVertices;
  Coordinate3D_dbl Vertices[200000];
}

struct DXF
{
     char strFilename[500];
     
     DXF_Header MyHeader;    
     DXFEntities MyEntities;

     //normals
     int DONE_NORMALS;
     int DONE_SMOOTH_NORMALS;
     Coordinate3D_dbl SmoothNormal[200000];
     Coordinate3D_dbl Normal[200000];

     //functions
     void ReadFile();
     void CalculateSmoothNormals();
     void CalculateNormals();
}

//Reads a DXF file strFilename
//Public
void DXF::ReadFile()
{
  ifstream input(strFilename);
}

void DXF::CalculateSmoothNormals()
{
}

void DXF::CalculateNormals()
{
}
0
 
LVL 1

Author Comment

by:MitchBroadhead
ID: 6444381
PS I would give points to both answers if they work, as i wouldn't want anyone to work for nothing!
0
 
LVL 4

Expert Comment

by:jtwine100697
ID: 6444635
> A more appropriate solution, IMO, would be to use an initialization function. [...]

You are correct: using the function eliminates the "when does my object get created/initialized issue", by allowing you to control when the object gets instantiated (first entry into the function), and is a better way to do it.  (And yes, it is from one of Scott Meyers books. :)

I was merely trying to show some ways of obtaining the required result.

> [References] That's not accurate, given the fact that you can use initialization functions to return references.

I was referring to declaring a reference, in the way of:

   ifstream &ifsMyStreamReference;  // This Would Need To Be Initialized.

The reference has to refer to something.  Returning a reference implies that you have an object somewhere that you are returning the reference to (the static ifstream object "d" in your example).

----------

Having the stream as a member of your class/struct seems like a good idea here.  

> If there is any performance increase in passing the pointer (as it is only 3 functions), then someone can show that method too!

If you are talking about passing a pointer/reference to the methods instead of having them use a member variable, I do not believe believe that there would be any difference: Member variables are accessed through the "this" pointer, which requires a pointer dereference, anyway, and, at least on MSVC++, references are implemented as pointers behind the scenes, so there is no difference there.

-=- James.
0
 
LVL 2

Accepted Solution

by:
smitty1276 earned 200 total points
ID: 6446667
MitchBroadHead... your code looks fine, except for the fact that the ifstream instance that you use to open the file is local to the ReadFile() function.  Move it into your structure so that all of the structures functions can access it, like so:

struct DXF
{

    ifstream input;
    char strFilename[500];
   
    DXF_Header MyHeader;    
    DXFEntities MyEntities;

    //normals
    int DONE_NORMALS;
    int DONE_SMOOTH_NORMALS;
    Coordinate3D_dbl SmoothNormal[200000];
    Coordinate3D_dbl Normal[200000];

    //functions
    void ReadFile();
    void CalculateSmoothNormals();
    void CalculateNormals();
}

//Reads a DXF file strFilename
//Public
void DXF::ReadFile()
{
 input.open(strFilename);
}
0
 
LVL 1

Author Comment

by:MitchBroadhead
ID: 6478965
cheers smitty.
that is what i was looking for!
0

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses
Course of the Month10 days, 11 hours left to enroll

764 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question