Solved

making ifstream available to other functions

Posted on 2001-08-30
17
429 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
  • 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
 
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
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 50 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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

760 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

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now