• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 507
  • Last Modified:

making ifstream available to other functions

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
MitchBroadhead
Asked:
MitchBroadhead
  • 4
  • 3
  • 3
  • +4
1 Solution
 
TriskelionCommented:
Can you pass a pointer to it into the other functions?
0
 
MitchBroadheadAuthor Commented:
how?
i would prefer to make it globally available, if possible
0
 
jtm111Commented:
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
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
AssafLavieCommented:
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
 
AxterCommented:
Can you post some of your code?
0
 
TriskelionCommented:
Pointer / Reference
Same general concept.
0
 
jtwine100697Commented:
> 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
 
jtm111Commented:
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
 
smitty1276Commented:
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
 
jtwine100697Commented:
> > 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
 
AssafLavieCommented:
>> 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
 
smitty1276Commented:
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
 
MitchBroadheadAuthor Commented:
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
 
MitchBroadheadAuthor Commented:
PS I would give points to both answers if they work, as i wouldn't want anyone to work for nothing!
0
 
jtwine100697Commented:
> 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
 
smitty1276Commented:
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
 
MitchBroadheadAuthor Commented:
cheers smitty.
that is what i was looking for!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 4
  • 3
  • 3
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now