Consider this code.
//header.h
int x;
//otherSource.cpp
#include "header.h"
//main.cpp
#include "header.h"
...
int main()
{
}
In this case compiler erred with the message. "fatal error LNK1169: one or more multiply defined symbols found"
but when I add static before x, it compiles without errors.
And here is the second case.
//header.h
class A
{
public:
void f(){}
static int a;
};
int A::a = 0;
/otherSource.cpp
#include "header.h"
//main.cpp
#include "header.h"
...
int main()
{
}
In this case compiler again erred with multiple declaration.
Can anybody explain me the behavior we static variables in classes and in global declarations?? Thanks in advance.
The issue with the static member variable is that you have the definition occur in the header file. If you #include the file in multiple source files, you have multiple definitions of the static member variable.
To fix this, the header file should consist only of this:
#ifndef HEADER_H
#define HEADER_H
// In the header file
class A
{
public:
void f(){}
static int a;
};
#endif
The definition of the static variable a should be in one and only one module. The obvious place for this is in your main.cpp.
#include "header.h"
int A::a = 0; // defined here
int main()
{
}
Declare x as extern in header.h to tell the compiler that x will be defined somewhere else:
extern int x;
Then define x once in the source file which you think is most fitting.
For example in otherSource.cpp:
int x = some_initial_value;
Related
I've got two files, list.cpp and Header.h. Segments of the files are below. I know that if the header file is for a class, it is setup different. E.g.
class MyClass
{
public:
void foo();
int bar;
};
However, since I'm not really working with a class here (correct me if I'm wrong), am I not able to declare things under public: and private like below?
Also, if I were to place the global variable rescan in the header file as a member variable, below the function definitions, only the main function can see the variable. Why is it not within the scope of the other functions?
list.cpp:
#include <boost/algorithm/string.hpp>
#include <vector>
using namespace std;
vector<int> results;
bool rescan;
int main()
{
vector<vector<string>> list;
int success = readFile(list);
vector<vector<string>> bad = findMe(list);
system("pause");
return 0;
}
vector<vector<string>> findMe(vector<vector<string>> find)
{
rescan = true;
}
Header.h:
#pragma once
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include <string>
#include <vector>
std::vector<std::vector<std::string>> findMe(std::vector<std::vector<std::string>>);
#endif
EDIT: I tried this in my header file:
public:
bool rescan;
But I got "syntax error: 'public'
If you want your global to be visible in other translation units (TU) (other files), you have to declare them extern in those other TUs:
Header.h:
// Include guard omitted
extern bool rescan; // Declaration
file.cpp
#include "Header.h"
bool rescan = false; // Definition
// ...
file2.cpp
#include "Header.h" // To see extern bool rescan;
void foo()
{
rescan = true;
}
// ...
I have the following header helper.h:
#ifndef ADD_H
#define ADD_H
class Helper{
public:
static float calculateSpriteSize(float imgSize, float screenSize);
};
#endif
This is my helper.cpp:
#include "block.h"
#include "helper.h"
float Helper::calculateSpriteSize(float imgSize, float screenSize)
{
return ((imgSize/screenSize)*100);
}
But, for some reason, when I call my function calculateSpriteSize on my running code by doing:
#include "header.h"
int main(void){
float h = Helper::calculateSpriteSize( 168.0f, 170.0f );
)
I get the following error:
error: incomplete type 'Helper' used in nested name specifier
Any help would be appreciated.
Block.h looks as follows:
#ifndef ADD_H
#define ADD_H
class Block{
private:
int imgID;
int life;
float price;
public:
Block();
void setImgID(int imgID);
int getImgID();
};
#endif
And block.cpp looks as follows:
#include "block.h"
Block::Block()
{
}
void Block::setImgID(int imgID)
{
this->imgID = imgID;
}
int Block::getImgID()
{
return imgID;
}
UPDATE: I added Helper to the class definition as suggested by Rakete1111. This did not fix the issue though.
UPDATE 2: Changed forward declaration to include. Added other include that was in my code in case its important.
The type introduced by forward declaration is incomplete type. But member function invoking requires the type to be complete, otherwise how does the compiler know whether the member exists or not, and its signature?
You need to include the header file.
#include "helper.h"
int main(void){
float h = Helper::calculateSpriteSize( 168.0f, 170.0f );
)
EDIT
You're using the same macro ADD_H in both "block.h" and "helper.h". It means for
#include "block.h"
#include "helper.h"
the second including would fail, the content of helper.h won't be included at all.
Change the including guard macro name to be unique, better to make it conform to the name of file name. Such as HELPER_H and BLOCK_H.
I have a header file that declares a class, and I want this class to access an integer that has been declared in the main cpp C++ file (i.e. another file than the class' one). I have been searching on Google and found nothing relevant. How can I do this?
To share a global variable among source files, use the extern keyword.
main.cpp
#include "foo.h"
int global_var=0;
int main()
{
foo();
return 0;
}
foo.h
#ifndef FOO_H
#define FOO_H
extern int global_var;
void foo();
#endif
foo.cpp
#include "foo.h"
int foo()
{
global_var=1;
}
Move the integer in main.cpp into a function, make it static there, have the function return a reference to it and put the function into a header file of its own which the class header file (or implementation file, if appropriate) includes.
integer.h:
#ifndef INTEGER_H // use some better, longer name here
#define INTEGER_H
int &Integer();
#endif
integer.cpp:
#include "integer.h"
int &Integer()
{
static int i = 0;
return i;
}
Access the integer like this:
int x = Integer(); // copy
Integer() = 123; // assign
I want to modify object "t1" of the class "abc" in "update" function which is defined in different file(temp2.cpp) than where "t1" is defined(temp1.cpp). I tried to use extern but that resulted in error. Please suggest nice way of doing this.
temp1.ccp
#include<iostream>
#include "test2.cpp"
using namespace std;
class abc{
public:
int x;
char y;
void printxy(){
cout<<x<<y<<endl;
}
};
abc t1;
int main(){
update();
return 0;
}
test2.cpp
extern abc t1;
void update(){
t1.x=5;
t1.y='A';
t1.printxy();
};
In file included from test.cpp:2:0: test2.cpp:1:8: error: `abc' does not name a type
extern abc t1;
^
test2.cpp: In function `void update()':
test2.cpp:3:2: error: `t1' was not declared in this scope t1.x=5;
You include test2.cpp before the declaration of class abc: the included file just gets expanded at the location where the #include occurs. You might want to use your code with the compiler's -E option to see how the file looks after preprocessing (in which case you probably also want to omit the #include <iostream> as it will produce lots of output).
In general, it isn't a good idea to include .cpp files. Did you mean the declarations to be a header file (e.g., test2.h) and include that at the type of test2.cpp? In that case the order of the declaration would be OK.
Finally I got it. Thanks for your comments :)
class.h
class abc{
public:
int x;
char y;
void printxy(){
std::cout<< x << y <<std::endl;
};
};
func.h
extern abc t1;
void update(){
t1.x=5;
t1.y='A';
t1.printxy();
};
main file
#include <iostream>
#include "class.h"
#include "func.h"
abc t1;
int main(){
update();
return 0;
}
Output
5A
I have written this header file (header1.h):
#ifndef HEADER1_H
#define HEADER1_H
class first ;
//int summ(int a , int b) ;
#endif
and this source files (header1.cpp and main.cpp):
#include <iostream>
#include "header1.h"
using namespace std;
class first
{
public:
int a,b,c;
int sum(int a , int b);
};
int first::sum(int a , int b)
{
return a+b;
}
#include <iostream>
#include "header1.h"
using namespace std;
first one;
int main()
{
int j=one.sum(2,4);
cout << j<< endl;
return 0;
}
But when I run this program in codeblocks , I give this Error :
aggregate 'first one' has incomplete type and cannot be defined .
You can't put the class declaration in the .cpp file. You have to put it in the .h file or else it's not visible to the compiler. When main.cpp is compiled the type "first" is class first;. That's not useful at all because this does not tell anything to the compiler (like what size first is or what operations are valid on this type). Move this chunk:
class first
{
public:
int a,b,c;
int sum(int a , int b);
};
from header1.cpp to header1.h and get rid of class first; in header1.h
You need to declare the whole class in a headerfile (that is included every place the class is actually used). Oterhwise, the compiler won't know how to "find" sum in the class (or how much space it should reserve for the class).
If you're using a main function as well, just define the class at the top and define the main later. It is not necessary to explicitly create a separate header file.