I've got 3 files that relate to this problem. file.h, file.C and user.C.
file.h has a private member, fstream logs.
In file.C's constructor it opens logs. It doesn't do this in the constructor, but the constructor calls a function OpenLog().
file.h also has an inline close function:
CloseLog() {if (logs) logs.close();}
The file user.C has an exit function which creates an instance of file, then calls CloseLog. It seg faults at this point. I created some other dummy tests, and it appears as though logs is lost in the mix somewhere ...
Going from file.C to user.C and then back to file.C causes this. If I have fstream logs as a global in file.C then it works - but I'd rather avoid a global.
Any thoughts on what I should do here? Please let me know if I should post more code about this, I can set up some dummy stuff to demo this better.
** Here's more code, as requested - I can't copy and paste, so forgive the lack of it please **
I will call the classes helpME.h, helpME.C and user.C
//helpME.h
#ifndef _helpME_H
#define _helpME_H
#include < iostream>
#include < fstream>
//various includes
class helpME {
private:
fstream logs;
public:
void CloseLog() {if (logs) logs.close();}
};
#endif
//end helpME.h
//helpME.C
void helpME::helpME(int argc, char** argv)
{
//various code
OpenLog();
}
void helpME::OpenLog()
{
//logname is set above, i had a print statement before that showed this is correct
logs.open(logname, ios::in | ios::out | ios::trunc);
}
//end helpME.C
//user.C
void user::quitHelpME(item)
{
helpME* hME = (helpME*) item;
hME->CloseLog();
}
//end user.C
Again - please forgive the lack of clarity, I'm thinking I may have just confused things more by adding this ... this code is on another box and can't be copied over.
void user::quitHelpME(item)
{
helpME* hME = (helpME*) item;
This doesn't create an instance, it's using C style casting to cast from whatever item is to a pointer to helpME.
if item is NULL then calling a method on it will seq fault.
otherwise still not enough detail in your example to give you an answer, the code present seems sound.
Because you've declared your variable in the .h file, you have two copies of it. The compiler doesn't 'see' .h files, it just copies/pastes what is in the file into the .C files, so, that's why you have two copies of the variable.
Declare the variable as extern in the .h file, and declare it again without the extern in only one .C file and don't use static in any declaration of that file.. It should fix your problem.
Related
I have been searching online for solutions to this rather simple problem. My goal is to call a function from a separate .cpp file in my main.cpp file. What I have found thus far has told me to define my function in a separate .cpp file (averageScore.cpp) which looks like:
void averageScore()
{
"Blah, Blah, Blah"
}
And then declare the function as a prototype in a header file (Lesson1.h) which looks like:
#include "C:/averagescore.cpp"
void averageScore();
And finally call the function again in the main.cpp:
#include "Lesson1.h"
int main()
{
averageScore();
return 0;
}
I am currently a CS student and my overall objective with this method of organization and execution is to create a single project for all of the rudimentary programs we must create on a weekly basis instead of creating a new project for every single program. For reference, I am using VScode and have used the following link to help me thus far:
http://www.cplusplus.com/forum/beginner/97779/
My condolences and gratitude are extended to anyone who has taken the time to read through this and help me out!
To achieve what you want, you must create a header file, and declare your function there, for example:
lesson1.h
void averageScore();
In a .cpp file, you define that function and include the header you just created:
lesson1.cpp
#include "lesson1.h"
void averageScore(){
// Do what you want in this function
}
Then you can call that function in your main.cpp by including "lesson1.h":
main.cpp
#include "lesson1.h"
int main()
{
averageScore();
return 0;
}
So, i have taken some ready code from a co-worker and build my own into theirs. The code compiles without warnings. The header contains a class and some declarations. The cpp file implements the methods. If i try to declare an extra method into the header file, there's absolutely no problem. But when i try to declare an extra variable (specifically char*) and use it into the cpp file, it compiles but creates abnormailites(programm does not do what it was doing, even with one declaration). If i declare the variable into the cpp file it works fine. I'm using dev c++. Is there maybe a linker issue?
this creates problems:
.h file:
class foo{
char* foo_char;
bool a_method();
}
.cpp file:
bool a_method(){
//do smthing
}
this is not:
.h file:
class foo{
bool a_method();
}
.cpp file:
char* foo_char;
bool a_method(){
//do smthing
}
Based on the initial writeup, I thought it might be an external variable declaration, but now we have sample code to work with. Let's assume this is real code.
This is the code from the latest edit of the question:
foo.h
class foo {
char* foo_char;
bool a_method();
}
foo.cpp
bool a_method() {
//do smthing
}
Okay, this is wrong. First, you need it to really be this:
bool foo::a_method() {
}
And your second example doesn't really make sense at all. You've moved your variable outside of the class definition, so it's no longer a class variable. Maybe that's what you want, but I don't think so.
And, of course, you still aren't indicating that a_method() is defined as a class method of foo when you write the code.
Try fixing this stuff and see if you do better.
Do you have a book? It seems to me you need to back up and read from the beginning. This is the very most basic parts of programming.
I'm trying to get the benefits of splitting without two files. Split compilation without splitting storage.
I understand the benefits of separating .h and .cpp files, but I really dislike having the files be separate, specifically when the classes are tiny and each file could fit on the same page.
Is there a precompiler option, or perhaps any other trick which would allow me to keep the benefits of separation, while having the text all in the same place? For example:
EDIT: please do not focus too much on this example. It was meant to show off an imaginary pre-processor arg #CPP_SPLIT. The actual code is unimportant, please, please ignore it.
// TinyClass.h
class TinyClass {
TinyClass();
int answerToLife();
}
// the following is a fake compiler arg
// in this example it would be totally unnecessary,
// but many of my classes have some form of circular referencing
// and can not include all the code in the .h file
#CPP_SPLIT
TinyClass::TinyClass() {}
TinyClass::answerToLife() { return 42; }
#CPP_SPLIT_END
I'm not sure it's worth the effort, but you could place the contents of your .cpp file into #ifdef'd sections, like this:
#ifdef PART_ONE
[...]
#endif
#ifdef PART_TWO
[...]
#endif
#ifdef PART_THREE
[...]
#endif
... and then recompile the file over multiple passes, like this:
g++ -DPART_ONE -opart1.o myfile.cpp
g++ -DPART_TWO -opart2.o myfile.cpp
g++ -DPART_THREE -opart3.o myfile.cpp
g++ -o a.out part1.o part2.o part3.o
You can simply put the implementation directly in the header like this:
// TinyClass.h
class TinyClass {
TinyClass() {}
int answerToLife() { return 42; }
};
Also inline might help to do what you want:
// TinyClass.h
class TinyClass {
TinyClass();
int answerToLife();
}
inline TinyClass::TinyClass() {}
inline int TinyClass::answerToLife() { return 42; }
Another potential solution to this appears to be the proposed c++ modules standard. If you happen across this many years down the line, look there.
I'm new to C++ and trying to make a map that all the source files will be able to access. Here is a simplified version of the problematic code. Every header file has a header guard, I just didn't type them here.
// main.cpp
#include "client.hpp"
int main(void){
init();
search();
}
// util.cpp
#include "util.hpp"
std::map<int, STUDENT_TYPE> dataBase;
init(){
dataBase[0] = STUDENT_TYPE(14, 4.0);
// more students....
}
// util.hpp
#include <map>
struct STUDENT_TYPE{
int age;
int grade;
STUDENT_TYPE(int age, int grade) : age(age), grade(grade){}
};
extern std::map<int, STUDENT_TYPE> dataBase;
// client.cpp
#include "client.hpp"
void search(){
std::cout << dataBase[0].grade << std::endl;
}
// client.hpp
#include "util.hpp"
void search();
The problem is that the compiler failed to build at the search function. It gives a big chain of errors. The last error or the cause of all the error is that the constructor of STUDENT_TYPE require 2 fields while given 0. I suspect that client can't access the STUDENT_TYPE struct inside the dataBase. I don't how to fix it or exactly how it happened. I just want a big table of students that all the files in the program can access.
The compiler is telling you exactly what's wrong. Your student type doesn't have a default constructor and it's being used.
Why is it being used?
Because map::operator [] will create a default constructed instance to return if an entry doesn't yet exist for that key. Even if this never happens, the compiler still has to compile that branch and it can't here.
Two ways to fix:
Give your student type a meaningful default.
Don't use map::operator[]. Instead use map::find.
First solution; don't have a global data structure. There is normally no need at at all to have such a thing.
Secondly, understand what header guards do - they prevent the body of a header file being included in the same translation unit. They have no effect if the header file is included in multiple .cpp files.
Thirdly, when you post questions about problems here, post the full text of the error messages you are getting.
OK folks. I have fixed the error by moving the variable definition, but I do not understand why there is a problem.
Simplified Background: I have an object and I want to track all instances of that object in a list, so I simply created a List<> static member of the class. Below was a simple representation that allowed me to play with it. If I have the line marked as "this line" in the static library. I get a run time error. The object is defined in a header file and is the same header file in both places. If I move "this line" to the code in my final application and it works.... Why? I just don't understand why it is different.
#include "stdafx.h"
#include <list>
using namespace std;
class someobject
{
public:
someobject()
{
// do some stuff.
theStaticList.push_back(this);
}
void func()
{
printf("Made it!!\n");
}
static list<someobject*> theStaticList;
};
list<someobject*> someobject::theStaticList; //*** This line
someobject global;
int main()
{
someobject initial;
initial.func();
global.func();
list<someobject*>::iterator iter;
printf("\n\nLoop the Static List\n");
for (iter = someobject::theStaticList.begin(); iter != someobject::theStaticList.end (); iter++)
(*iter)->func();
return 0;
}
If you put that line in a header file, then include the header into two or more source files, you're defining the list object in each source file where the header gets included.
This violates the one definition rule, so the linker will quite rightly give you an error when you do it.
You want to define the object in one (and only one) source file. For a library, that should be some object file in the library, not the user's source file though (at least as a general rule).