I am reading this book called "C++ How to Program" from Deitel and I am still a beginner in this. I know Java, so I am trying to get familiar with the C++ syntax and how it works.
My code is the following:
file >> gradebook_interface.h
#include <string>
//#include <unordered_map>
using namespace std;
//specifing interface
class gradebook_interface
{
public:
//constructor
gradebook_interface(string);
void reset_Coursename();
void setCoursename(string);
string getCourseName();
void displayMessage();
void add_to_hashmap(string,int);
private:
//hashmap init
//unordered_map <string, int> course_map;
string courseName;
};
file >> gradebook_interface.cpp
#include <iostream>
//including interface "gradeinterface"
#include "gradebook_interface.h"
using namespace std;
//constructor from interface
gradebook_interface::gradebook_interface(string name)
{
setCoursename(name);
}
void gradebook_interface::setCoursename ( string name )
{
courseName = name;
}
string gradebook_interface::getCourseName()
{
return courseName;
}
void gradebook_interface::displayMessage()
{
cout << "First C++ application\n" << getCourseName() << "!" << endl;
}
//interfac's methods
void gradebook_interface::reset_Coursename()
{
courseName = "null";
cout << "The course name has been reseted! Value is: " << getCourseName() << endl;
}
void gradebook_interface::add_to_hashmap(string, int)
{
//course_map["test_course"] = 14;
//cout << "Hashmap value just entered:" << endl;
//cout << course_map["test_course"] << endl;
}
file >> gradebook_main.cpp
#include <iostream>
#include "gradebook_interface.h"
using namespace std;
int main()
{
gradebook_interface gradebook_1 ("Maths");
gradebook_interface gradebook_2 ("Greek");
cout << "gradebook 1 " << gradebook_1.getCourseName() << endl;
cout << "gradebook 2 " << gradebook_2.getCourseName() << endl;
};
The book uses Visual Studio that I can't use because I am on ubuntu.
I read somewhere that if you compile C++ code using "gcc" it invokes automatically "g++".
But I get an error, so I am forced to use g++.
My first question is, can I use gcc (any parameters needed?)?
My second question is, how does the linker works?
My third question is why do I get a segmentation fault when I try to run this ??
thanks
I have no problem compiling your program in this way:
g++ -O2 -g main.cpp gradebook_interface.cpp -o main
In fact I used the following Makefile
all: main
main: main.cpp gradebook_interface.cpp
g++ -O2 -g $^ -o $#
and simple issued make && ./main outputting:
gradebook 1 Maths
gradebook 2 Greek
I ran it under valgrind; so far no detected memory errors. I haven't looked at your code
Edit On the How does the linker work part:
If you rewrote that Makefile like so:
all: main
CPPFLAGS+=-O2 -g
main: main.o gradebook_interface.o
g++ $(CPPFLAGS) $^ -o $#
It would result in the following build steps:
g++ -O2 -g -c -o main.o main.cpp
g++ -O2 -g -c -o gradebook_interface.o gradebook_interface.cpp
g++ -O2 -g main.o gradebook_interface.o -o main
which shows how to do the compile steps (-c) separately from the link step. The link step could in that case be written as the explicit call to ld intead, but you'll have to specify the runtime libraries for libgcc and libstdc++ yourself
Related
I always arranged my C++ headers and source files this way:
prog.h
#include <iostream>
class Prog
{
public:
Prog(std::string);
~Prog();
void printName();
private:
std::string name;
};
#include "prog.cpp"
prog.cpp
Prog::Prog(std::string n):
name(n)
{
std::cout << "Program \"" << name << "\" started.\n";
}
Prog::~Prog()
{
std::cout << "Program \"" << name << "\" ended.\n";
}
void Prog::printName()
{
std::cout << "Program name is: \"" << name << "\".\n";
}
main.cpp
#include "prog.h"
int main()
{
Prog prog {"MyCalculator"};
prog.printName();
return 0;
}
But I recently discovered that it's common to arrange them this other way:
prog.h
class Prog
{
public:
Prog(std::string);
~Prog();
void printName();
private:
std::string name;
};
prog.cpp
#include <iostream>
#include "prog.h"
Prog::Prog(std::string n):
name(n)
{
std::cout << "Program \"" << name << "\" started.\n";
}
Prog::~Prog()
{
std::cout << "Program \"" << name << "\" ended.\n";
}
void Prog::printName()
{
std::cout << "Program name is: \"" << name << "\".\n";
}
main.cpp
#include <iostream>
#include "prog.h"
int main()
{
Prog prog {"MyCalculator"};
prog.printName();
return 0;
}
I find the first method more convenient, so is there any reason why I should prefer the second method over the first one?
Header files shouldn't include source code.
I think the first method could provoke dependency errors in a complex enough project (for example, using circular dependencies), because don't separate declaration and definition.
The compilation time is faster in the second one, because you can compile each source file separately.
Also, you might find this question useful.
The first version is what the book "Accelerated C++" (ed. 2000) suggests to do when first introducing header files for class declarations.
I suppose the second version can be seen as more elegant because it groups together all #include pre-compiler statements at the beginning of the program.
I am trying to build plugins in c++ using boost library. helper.h
Header file:
#include <string>
#ifndef HELPER_H
#define HELPER_H
class Helper
{
public:
std::string s;
void helper_new(std::string a);
};
#endif
I defined the member function in a file helper.cpp
#include "helper.h"
namespace boostfs = boost::filesystem;
namespace boostdll = boost::dll;
namespace dll = boost::dll;
// Member Functions()
void Helper::helper_new(std::string a)
{
//int i=0;
std::cout<<"Inside helper_new function!!";
std::cout<<"\n";
std::cout<<a;
std::cout<<"\n";
/*std::ofstream MyFile("/home/deepansh/Desktop/Plugin_example/outputs/helper.txt");
std::cout << "Writing in helper.txt\n"; */
/*for(i=0;i<LONG_MAX;i++)
for(int j=0;j<LONG_MAX;j++);*/
/*MyFile<<a+" ";
MyFile<<i;
MyFile<<"\n";
MyFile.close();*/
std::cout << "Done\n";
}
int main() {
Helper obj;
std::string a;
std::cout<<"Enter string u want to write?";
std::getline(std::cin, a);
obj.s=a;
int choice=1;
std::cout<<"which strat to use? \'1\' or \'2\' ?(default is 1)";
std::cin>>choice;
std::string file="strat"+std::to_string(choice);
boostfs::path lib_path = boostfs::current_path();
boost::filesystem::path p2(std::string(lib_path.string()).append("/plugins/").append(file).append(".so"));
boost::shared_ptr<plugin_api> plugin; // variable to hold a pointer to plugin variable
std::cout << "Loading the plugin" << std::endl;
plugin = dll::import<plugin_api>( // type of imported symbol is located between `<` and `>`
p2, // path to the library and library name
"plugin", // name of the symbol to import
dll::load_mode::append_decorations // makes `libmy_plugin_sum.so` or `my_plugin_sum.dll` from `my_plugin_sum`
);
plugin->handle_task(obj);
std::cout << plugin->print() << std::endl;
}
I called the member function from another file with the help of object of Helper class passed to it as argument(this is compiles as so file) strat1.cpp
#include "../helper.h"
#include <string>
namespace my_namespace {
class strat : public plugin_api {
public:
strat() {
std::cout << "Constructing start" << std::endl;
}
std::string print() const {
return "Hello from strat 1";
}
int handle_task(Helper a) {
//long i=0;
//std::ofstream fout;
//fout.open("/home/deepansh/Desktop/Plugin_example/outputs/strat1.txt");
std::cout<<"Inside strat 1";
std::cout<<"\n";
/*for(i=0;i<LONG_MAX;i++)
for(int j=0;j<LONG_MAX;j++);*/
//fout<<a.s+" ";
//fout<<i;
//fout<<"\n";
//fout.close();
std::cout<<a.s;
std::cout<<"\n";
std::cout<<"going to the helper class function.";
std::string p="Hello man. What's up?";
a.helper_new(p); //error is here
return 0;
}
~strat() {
std::cout << "Destructing strat ;o)" << std::endl;
}
};
I am getting this error ./a.out: symbol lookup error: /home/deepansh/Desktop/Plugin_example/plugins/strat1.so: undefined symbol: _ZN6Helper10helper_newENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
When compiling the code can someone help. compiling:
Convert the plugin library(plugin implementation) to object file by using:
gcc -c -Wall -Werror -fpic strat1.c ../helper.cpp //here -wall and -Werror are for warnings
Then convert the .o files to .so files using(creating shared library from object file) :
gcc -shared -o strat1.so strat1.o
g++-8 helper.cpp -L/usr/lib/x86_64-linux-gnu -lboost_filesystem -L/usr/lib/x86_64-linux-gnu -lboost_system -ldl
when I run the executable a.out the error occurs
I'm facing a problem for the past couple of days.
First of all, I had a project that I've done. But now I've to split it's classes.
Here's how I split the classes (a class as an example):
Header file:
#ifndef QUESTION_H
#define QUESTION_H
#include <string>
#include <iostream>
#include <fstream>
#include "Answer.h"
using namespace std;
// Name -- hold a first and last name
class Question {
protected:
string type; // Type of the question, e.g MC or TF
string text; // Text of the question
public:
// Default constructor
Question ();
// Getters and setters
string getType();
string getText();
void setType (string t);
void setText (string t);
// displayText -- Display the text of the question, unformatted at present
void displayText();
// Template pattern -- algorithm in parent which does its work calling child methods
virtual void displayAnswers();
virtual void display ();
// Virtual pure functions that must be implemented by each derived class
virtual int grade (Answer*); // grade a given answer
virtual Answer* readAnswer(istream &); // read a user's answer
};
#endif
Alright, now here is the implementation:
#include "Question.h"
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
Question::Question () { type = ""; text = ""; }
// Getters and setters
string Question::getType() { return type; }
string Question::getText() { return text; }
void Question::setType (string t) { type = t; }
void Question::setText (string t) { text = t; }
// displayText -- Display the text of the question, unformatted at present
void Question::displayText() {
cout << text;
}
// Template pattern -- algorithm in parent which does its work calling child methods
void Question::displayAnswers(){ }// Require derived classes to implement
void Question::display () {
Question::displayText();
Question::displayAnswers(); // Call derived class's displayAnswers
}
// Virtual pure functions that must be implemented by each derived class
int Question::grade (Answer*){ return 0; } // grade a given answer
Answer* Question::readAnswer(istream &){ return 0; } // read a user's answer
Ok, so I've done the other classes the same exact way.
Now what's left is the MakeFile, here it is:
project: Question MCQuestion TFQuestion Answer IntAnswer CharAnswer Main
g++ -std=c++11 Question MCQuestion TFQuestion Answer IntAnswer CharAnswer Main -o project
.cc.o:
g++ -std=c++11 -c <−o#
Now when I try running make it brings up this message:
g++ Question.cpp -o Question
/usr/lib/gcc/i586-suse-linux/4.7/../../../crt1.o: In function `_start':
/home/abuild/rpmbuild/BUILD/glibc-2.17/csu/../sysdeps/i386/start.S:113: undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [Question] Error 1
Can somebody explains it? or what am I doing wrong?
Thanks.
Edited:
Main.cc :
#include <iostream>
#include <fstream>
#include <string>
#include "Question.h"
#include "MCQuestion.h"
#include "TFQuestion.h"
#include "Answer.h"
#include "IntAnswer.h"
#include "CharAnswer.h"
#include <vector>
using namespace std;
int main () {
vector<Question *> questions; // Holds pointers to all the questions
ifstream infile ("questions.txt"); // Open the input file
int totalCorrect = 0; // Initialize the count from number of correct answers
// Read each question and place it into the questions vector
string questionType;
while ( getline (infile, questionType) ) {
if (questionType == "MC") {
MCQuestion *mc = new MCQuestion();
mc->read(infile);
questions.push_back(mc);
}
else if ( questionType[0] == 'T' or questionType[0] == 'F' ) {
TFQuestion* tf = new TFQuestion();
tf->read(infile);
tf->setAnswer(questionType[0]);
questions.push_back(tf);
}
else {
cout << "Input file is corrupt. Expected to find MC, T or F; found \"" << questionType << "\" instead." << endl;
}
}
infile.close();
// Pose each question, read and grade answers, tally total
int questionNo = 0;
for (auto &question: questions) {
// Pose the question
questionNo++; cout << questionNo << ". ";
question->display();
// Get the user's answer
Answer* ans = question->readAnswer(cin);
// Grade it and increment total
int correct = question->grade(ans);
totalCorrect = totalCorrect + correct
// Inform the user as to whether or not they got the question correct
cout << "Your answer was " << (correct?"":"not ") << "correct\n" << endl;
}
// Print the overall score
cout << "Your overall score is " << totalCorrect << "/"
<< questions.size() << endl;
return 0;
}
You create Makefile with lot of mistakes:
Should be something like this:
project: Question.o
g++ -std=c++11 $^ -o $#
.cc.o:
g++ -std=c++11 -c $< -o $#
add other dependencies into project in similar way, not forget defining main function in some of your .cc files.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
Here's my make file:
#!/usr/bin/make -f
compiler = g++
compiler_flags = -Wall -I /usr/include/c++/4.5
debug_flags = -D DEBUG -g
binary_filename = sort_testing.bin
all: clean release
release:
$(compiler) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
debug: sort.o
$(compiler) $(debug_flags) $(compiler_flags) main.cpp sort.o -o $(binary_filename)
run:
./$(binary_filename)
clean:
rm -f *.o $(binary_filename)
sort.o:
$(compiler) $(debug_flags) $(compiler_flags) -c sort.cpp
Here are my C++ Files:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#endif
// sort.cpp
#include "sort.hpp"
namespace sort{
template<class T>
void swap(T* items, int index_a, int index_b){
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
}
// main.cpp
#include <iostream>
#include <exception>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
#include "sort.hpp"
using namespace sort;
#define NUM_INTS 5
int main(int argc, char** argv){
try{
cout << "\n\n\n";
srand(time(NULL));
int * int_coll = new int[NUM_INTS];
for (int x = 0; x < NUM_INTS; x++)
int_coll[x] = rand() % 100 + 1;
cout << "Before swap" << endl;
for (int x = 0; x < NUM_INTS; x++)
cout << "int " << x << " == " << int_coll[x] << endl;
cout << "\n\n\n";
cout << "Swapping ints" << endl;
swap<int>(int_coll, 0, 1);
cout << "AFter swap" << endl;
for (int x = 0; x < NUM_INTS; x++)
cout << "int " << x << " == " << int_coll[x] << endl;
}catch(exception& e){
cout << "Exception: " << e.what() << endl;
}
return 0;
}
And, here's my problem:
./make clean debug
rm -f *.o sort_testing.bin
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 -c sort.cpp
g++ -D DEBUG -g -Wall -I /usr/include/c++/4.5 main.cpp sort.o -o sort_testing.bin
/tmp/ccRl2ZvH.o: In function `main':
/home/dev/c++/sorting/main.cpp:33: undefined reference to `void sort::swap<int>;(int*, int, int)'
collect2: ld returned 1 exit status
make: *** [debug] Error 1
Any idea how to resolve this issue?
Template definitions need to either be visible at the point of use (so that they can be implicitly instantiated) OR you need to explicitly instantiate them (in this case the linker will bring the explicit instantiation and the usage together).
In your situation I would go with option one (and implicit instantiation). This means you need to move the template definition (of the template) into the header file:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T>
void swap(T*,int,int)
{
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
}
#endif
Alternatively (but less useful in the general case (but has its uses)) is explicit template instantiation. Here you define in sort.cpp which variants of the template you want to have defined.
// sort.cpp
#include "sort.hpp"
namespace sort{
template<class T>
void swap(T* items, int index_a, int index_b){
T t = items[index_a];
items[index_a] = items[index_b];
items[index_b] = t;
}
// Define an explicit function template instantiation.
// Here we define that the integer version of the template must exist.
template void swap<int>(int*,int,int);
}
This is useful when you want to limit the number of versions of a template are available.
Template definitions must be in the same file. So define the function in the header file itself.
Or include the .cpp file in the header at the bottom as:
// sort.hpp
#ifndef SORT_H
#define SORT_H
namespace sort{
template<class T> void swap(T*,int,int);
}
#include "sort.cpp" //<--------------- this!
#endif
You can not define templates in a .cpp file. The definition of swap should be in the sort.hpp file only. See this FAQ Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file? for more details.
Greeting Everyone
I'm trying to compile and run a multi-language code in C, C++ and fortran using gcc, g++ & f77 respectively in UNIX. My program consists of two parts, one in C, the other in C++. They interface via a main() writen in C+, while the fortran code can be ignored for this case.
I have been having numerous issues with this, most noticabbly a Segmentation Error thats been occuring as I run the executable. The previous two topics of mine have whittled it down, unfortunatly nothing seems to be solving the problem outright other than completely removing any input/output processes in either half of my program, which just isn't feasible.
Accessing public class memory from C++ using C
Output conflicts between C & C++
I need to locate the reason why I recieve Segmentation Errors when I use input/outputs in both parts of my program. All sources compile, all link successfully and I know that each part (C & C++) works when linked alone with no such Segmentation Errors (with modifications to let them work alone of course). I've included all the code that interfaces between the two parts and performs input/output functions.
Any help would be much appriciated.
Makefile
products: SlowDynamic.exe
SlowDynamic.exe: main.o SA.o mersenne.o CFE.o BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o MA_57.o blas.o MA_57_Depend.o Metis.o
f77 -L/usr/sfw/lib -R/usr/sfw/lib -lgcc_s -lstdc++ -o SlowDynamic.exe main.o \
SA.o mersenne.o CFE.o MA_57.o blas.o MA_57_Depend.o Metis.o\
BCs.o EMatrix.o Numbering.o KMatrix.o Solve.o
main.o: main.cpp
g++ -c -o main.o main.cpp
SA.o: SA.cpp
g++ -c -o SA.o SA.cpp
mersenne.o: mersenne.cpp
g++ -c -o mersenne.o mersenne.cpp
CFE.o: CFE.c
gcc -c -o CFE.o CFE.c
MA_57.o: MA_57.f
f77 -c -o MA_57.o MA_57.f
blas.o: blas.f
f77 -c -o blas.o blas.f
MA_57_Depend.o: MA_57_Depend.f
f77 -c -o MA_57_Depend.o MA_57_Depend.f
Metis.o: Metis.f
f77 -c -o Metis.o Metis.f
BCs.o: BCs.c
gcc -c -o BCs.o BCs.c
EMatrix.o: EMatrix.c
gcc -c -o EMatrix.o EMatrix.c
Numbering.o: Numbering.c
gcc -c -o Numbering.o Numbering.c
KMatrix.o: KMatrix.c
gcc -c -o KMatrix.o KMatrix.c
Solve.o : Solve.c
gcc -c -o Solve.o Solve.c
clean:
rm *.o Main.exe *.gpi
main.ccp
#include <iostream>
#include "SA.h"
using namespace std;
int main()
{
Initial.Initialize();
Parent.SA(Initial.Write);
system ("PAUSE");
return 0;
}
SA.h
#ifndef SA_H
#define SA_H
#include <vector>
class SimAnneal {
std::vector< std::vector<float> > DensityDomain;
float Solid_Ele_Num, Void_Ele_Num;
float Solid, Void;
double Energy;
double Time;
void Metropolis (double, int, int);
void Next_State (double, int);
double Schedule (double, int);
double ObjFunction ();
void Distribute ();
void Mutate ();
void Convert ();
void PrintDomain ();
void WriteResults (double, double, double, double, double);
public:
int x_max, y_max;
...
std::vector<float> DensityArray;
std::vector<float> EnergyArray;
...
void SA (int);
void Initialize ();
};
extern SimAnneal Initial, Parent, Child, Mutation, Best;
#endif
SA.cpp
include <math.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <vector>
#include "SA.h"
#include "CFE.h"
#include "randomc.h"
using namespace std;
SimAnneal Initial, Parent, Child, Mutation, Best;
...
void SimAnneal::Initialize ()
{
x_max = ReturnX();
y_max = ReturnY();
EnergyArray.resize(x_max*y_max);
DensityArray.resize(x_max*y_max);
...
Energy = ObjFunction();
}
...
void SimAnneal::PrintDomain ()
{
static ofstream OutputFile;
if (!OutputFile.is_open())
{
char FileName [] = "DensityDomain.txt";
OutputFile.open(FileName);
if (!OutputFile)
{
cerr << "Failed to open " << FileName << endl;
exit(EXIT_FAILURE);
}
//cout << "\nGenerating 'DensityDomain.txt'... \n" << endl;
}
for (int y = 0; y < y_max; y++)
{
for (int x = 0; x < x_max; x++)
{
OutputFile << DensityDomain[y][x] << " ";
}
OutputFile << endl;
}
OutputFile.close();
}
void SimAnneal::WriteResults (double i, double T, double x, double y, double z)
{
static ofstream OutputFile;
if (!OutputFile.is_open()) //check is file has been opened
{
char FileName [] = "Results.txt";
OutputFile.open(FileName);
if (!OutputFile)
{
cerr << "Failed to open " << FileName << endl;
exit(EXIT_FAILURE); //abort program
}
//cout << "\nWriting to file in progress... \n" << endl;
OutputFile << "Iterations" << '\t' << "Temperatures" << '\t' << "Sum Strain Energy" << endl; //<< "SwapNum1" << '\t' << "SwapNum2" << '\t' << "Distance" << endl;
OutputFile << endl;
Initial.Time = (int)time(0);
}
OutputFile << i << '\t' << T << '\t' << z << endl; //'\t' << y << '\t' << z << endl;
if (i == N_max || T <= T_abs)
{
Parent.Time = (int)time(0);
OutputFile << endl
<< "Settings: " << endl
<< "Initial Temperature: " << Initial.Temp << endl
<< "Temperature Iterations: " << i << endl
<< "Step Iterations: " << N_step << endl
<< endl
<< "Results: " << endl
<< "Final Temperature: " << Temp << endl
<< "Minimum: " << Energy << endl
<< "Computational Time (s): " << (Parent.Time-Initial.Time) << endl;
OutputFile.close();
}
}
CFE.h
#ifdef __cplusplus
extern "C" {
#endif
int ReturnX ();
int ReturnY ();
void CFE(float density[], float energy[], int Length);
#ifdef __cplusplus
}
#endif
CFE.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "BCs.h"
#include "EMatrix.h"
#include "Numbering.h"
#include "KMatrix.h"
#include "fg_types.h"
#include "Solve.h"
int ReturnX ()
{
FILE *infile;
infile = fopen("test05", "r");
int elemX,elemY;
fscanf(infile, "%i %i", &elemX, &elemY);
fclose(infile);
return elemX;
}
int ReturnY () { Same but returns elemY }
void CFE(float density[], float energy[])
{
// Extensive use of fscanf(), printf() & fprintf()
// and the following:
FILE *outfile;
outfile = fopen("File.txt", "w");
if(outfile == NULL){
}
else{
for(n=0;n<8;n++)
{
for(m=0;m<8;m++)
{
fprintf(outfile,"%f",KE[n][m]);
fprintf(outfile,"\t");
}
fprintf(outfile,"\n");
}
}
fclose(outfile);
}
I'd suggest going through your code with a critical eye, and checking out everything that looks even remotely odd.
I'd do it for you but C++ isn't in my rotation at the moment and I'm tripping on false positives. For example, this caught my eye:
if (!OutputFile.is_open())
{
char FileName [] = "DensityDomain.txt";
OutputFile.open(FileName);
if (!OutputFile)
{
cerr << "Failed to open " << FileName << endl;
exit(EXIT_FAILURE);
}
//cout << "\nGenerating 'DensityDomain.txt'... \n" << endl;
}
Half way down you're testing if OutputFile is null, after already calling is_open() and open() on it. It looked to me as if either 1) OutputFile won't be null or 2) you shouldn't be calling methods on it before you test it. But I was wrong.
See what I mean?