Class is not defined in implementation file - c++

When I try to compile my implementation file using g++ -c Sorting_Functions.cpp, I get this message
error: use of undeclared identifier 'IntSort'
IntSort.h
#ifndef INTSORT_H_
#define INTSORT_H_
#include "Sorting_Functions.cpp"
class IntSort
{
public:
IntSort();
void print();
private:
int arr[5];
int len;
};
#endif
Sorting_Functions.cpp
#include "IntSort.h"
using namespace std;
IntSort::IntSort()
{
arr[0] = 7;
arr[1] = 3;
arr[2] = 2;
arr[3] = 6;
arr[4] = 4;
len = 5;
}
// prints the lists to the user
void IntSort::print()
{
cout << "{ ";
for (int i = 0; i < len; i++) {
cout << arr[i] << " ";
}
cout << "}";
}

The problem is the inclusion of a source file (.cpp or .cc). Only header files (.h) should be included, and all source files should be compiled. Remove the source file #include and the code should be fine.
The "undeclared identifier" error is caused by Sorting_Functions.cpp including IntSort.h which in turn includes Sorting_Functions.cpp - the compiler will first see the type IntSort being used, which at this point has not yet been declared (which happens in IntSort.h after the #include).

Related

Using an initialized object from one .cpp in another .cpp file without classess

I'm trying to split some functionality between multiple .cpp files and I've got an issue. Let's say, I have:
Extra.h
#include "CustomClass.h"
namespace extraSpace
{
extern int justInteger;
extern CustomClass *complexObject;
}
Extra.cpp
include "Extra.h"
int extraSpace::justInteger = 1;
CustomClass *extraSpace::complexObject = new CustomClass;
complexObject->SomeProperty = 1; // Can't do this
Main.cpp
include "Extra.h"
int main()
{
std::cout << extraSpace::justInteger << "\n";
std::cout << extraSpace::complexObject->SomeProperty << "\n";
}
This code works well for justInteger variable. However, I cannot manipulate complexObject properties in Extra.cpp. Is there any simple workaround here?
I thought about creating some InitObject() function, but this would mean that I would have to change the object from Main.cpp, which I would rather not do.
CustomClass *extraSpace::complexObject = new CustomClass;
complexObject->SomeProperty = 1; // Can't do this
You can use a lamda.
CustomClass *extraSpace::complexObject = [] {
auto* complexObject = new CustomClass;
complexObject->SomeProperty = 1;
return complexObject;
}();

Error LNK2005 in C++ and ifndef don't work

I have a problem with Visual Studio 2012 & 2015 about the fact than it's seem than the "ifndef" don't work. I use the "ifndef" for "NAN" and "ifndef" for the header file and it's said these 2 errors (see the image). When I add the link "#include"Outil.h"" in the header of other file, I see the same message of error.
I always do like this before and it's always work. I don’t understand why it's doesn't work now even with only two files.
I also try to change the name of the first function "realoc_ungraded" but it's doesn't work and I get the same error.
Message of error
The message:
1) Warning: C4005: 'NAN': macro redefinition of math.h
2) Error: LNK2005: "struct tab_dynamo __cdecl realoc_ugraded(struct tab_dynamo,unsigned int)" (?realoc_ugraded##YA?AUtab_dynamo##U1#I#Z) already defined in main.obj Project1
3) Error: LNK1169: one or more multiply defined symbols found Projet
There is the code of the different file:
File main.cpp
#include"Outil.h"
int main(void) {
return 0;
}
File Outil.h
#ifndef LIBRARY_OF_TOOLS
#define LIBRARY_OF_TOOLS 0
#define _USE_MATH_DEFINES
//NAN not defined in Visual Studio 2012, so I use the def. of VS 2015
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
#include<iostream>
#include<string>
using namespace std;
#include<cmath>
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#define ERROR_ADRESSE 0xcccccccc //default when not initialised
#define DEFAULT_LENGHT_TAB 1
//-----------------------------------------
typedef double type_data; //the type for calculation
//-----------------------------------------
/*Struct for my array*/
typedef struct {
type_data *tab;
unsigned int length;
}tab_dynamo;
//-----------------------------------------
template<typename T>
bool verify_ptr(const T *ptr) {
return (ptr == NULL || ptr == (T*)(ERROR_ADRESSE));
}
//-----------------------------------------
template<typename T>
void see_tab(const T *tab, const unsigned int taille) {
unsigned int i;
cout << endl << endl;
if (verify_ptr(tab) == false && taille > 0) {
cout << endl;
for (i = 0; i<taille; ++i) {
cout << tab[i] << "\t";
}
}
cout << endl << endl;
}
//-----------------------------------------
template<typename T>
T* realoc_ungraded(const T* original_tab, unsigned int *length, const unsigned int new_length) {
T* new_tab = NULL;
unsigned int precedent_length = 0, i;
/*1) Exception case to directly exit*/
if (new_length == 0) {
return NULL;
}
/*2) Verification of the ptr of the length*/
if (verify_ptr(length)) {
length = (unsigned int*)calloc(1, sizeof(unsigned int));
assert(length);
}
precedent_length = *length;
*length = new_length;
/*4) Creation of the new tab.*/
new_tab = (T*)calloc(*length, sizeof(T));
assert(new_tab);
/*5) To transfert data of the original tab to the new tab*/
if (precedent_length != 0 && verify_ptr(original_tab) == false) {
for (i = 0; i < precedent_length && i < new_length; ++i) {
new_tab[i] = original_tab[i];
}
}
return new_tab;
}
//-----------------------------------------
//Version with the use of the struct "tab_dynamo"
tab_dynamo realoc_ungraded(tab_dynamo original_tab, const unsigned int new_length) {
tab_dynamo tableau = { NULL, 0 };
tableau.tab = realoc_ugraded(original_tab.tab, &original_tab.length, new_length);
tableau.length = new_length;
return tableau;
}
#endif
File Outil.cpp:
#include"Outil.h"
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
When preprocessor process these, the NAN is defined because it's not defined yet.
#include<cmath>
Then cmath maybe include math.h, and found NAN is defined by yours.
You can try to change the sequence of include and your definition.
#include <cmath>
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
B.T.W If you compile using gcc, you could use -E option to see the output of preprocessor and know how the preprocess expand the macros.

C++ Dynamic Array: A value of type "void" cannot be used to initialize an entity of type "int"

I am working on a C++ project for school in which the program will read in a list of numbers from a text file, store them in a dynamic array, then print them out to another text file. To be honest I'm a little lost with the pointers in this, and I am getting the error "A value of type "void" cannot be used to initialize an entity of type "int"" in my main source file.
Main.cpp (this is where I'm getting the error):
#include "dynamic.h"
int main
{
readDynamicData("input.txt","output.txt");
}
dynamic.cpp (the skeleton for the program):
#include "dynamic.h"
void readDynamicData(string input, string output)
{
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
int *temp = da.theArray;
da.theArray = new int[da.size];
ifstream in(input);
ofstream out(output);
in >> da.number; //prime read
while (!in.fail())
{
if (da.count < da.size)
{
da.theArray[da.count] = da.number;
da.count++;
in >> da.number; //reprime
}
else grow; //if there are more numbers than the array size, grow the array
}
out << "Size: " << da.size << endl;
out << "Count: " << da.count << endl;
out << "Data:" << endl;
for (int i = 0; i < da.size; i++)
out << da.theArray[i];
in.close();
out.close();
delete[] temp;
}
void grow(DynamicArray &da) //this portion was given to us
{
int *temp = da.theArray;
da.theArray = new int[da.size * 2];
for (int i = 0; i<da.size; i++)
da.theArray[i] = temp[i];
delete[] temp;
da.size = da.size * 2;
}
and dynamic.h, the header file:
#include <iostream>
#include <string>
#include <fstream>
#ifndef _DynamicArray_
#define _DynamicArray_
using namespace std;
void readDynamicData(string input, string output);
struct DynamicArray
{
int *theArray;
int count;
int size;
int number;
};
void grow(DynamicArray &da);
#endif
you have to add parenthesis to main or any function:
int main(){/*your code here ...*/};
2- you are using an unitialized objct:
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
so int* theArray is a member data and is uninitialized so welcome to a segfault
all the members of da are not initialized so you have to do before using it.
3- also you add parenthesis to grow function:
else grow(/*some parameter here*/); // grow is a function
4- using namespace std; in a header file is a very bad practice.
tip use it inside source
5- why making inclusion of iostream and string.. before the inclusion guard??
correct it to:
#ifndef _DynamicArray_
#define _DynamicArray_
#include <iostream>
#include <string>
#include <fstream>
/*your code here*/
#endif
main is a function so it needs brackets:
int main(){
// your code
return 0; // because it should return intiger
}
And. Your grow is also a function, so if you want to call it you write grow() and it needs DynamicArray as a parameter.
It is impossible to write working programs on C/C++ any programming language not knowing a basic syntax.

' was not declared in this scope' C++

I have some rude errors... I search the web about it, and i was able to read her everywhere, but still not fix my problem ...
Here is my main :
#include <iostream>
#include "SFML/Network.hpp"
#include "decode.hpp"
#include "listOfFunction.hpp"
#include "map.hpp"
void createSocket(){
unsigned short bindPort = 12800;
unsigned short clientPort;
int ret = 0;
sf::UdpSocket socket;
sf::IpAddress clientAddr;
sf::Packet packet;
Map mainMap;
if (socket.bind(bindPort) != sf::Socket::Done){
if (sf::Socket::Error) std::cout << "An unexpected error happened : Fatal Error !" << std::endl;
if (sf::Socket::NotReady) std::cout << "The socket is not ready to send/receive data yet !" << std::endl;
}
while(1){
packet.clear();
socket.receive(packet, clientAddr, clientPort);
std::string header = readFromPacket(packet);
ret = callFunction(packet, header, clientAddr, clientPort, mainMap, socket);
}
}
int main(){
createSocket();
}
Here are the errors :
error : 'Map' was not declared in this scope
error : expected ';'before 'mainMap'
error : 'mainMap' was not declared in this scope
error : callFunction was not declared in this scope
Map.cpp :
#include <iostream>
#include <vector>
#include "SFML/Network.hpp"
#include "map.hpp"
Map::Map(){
char number[5] = "\0";
int m_obstacle[80000] = {0};
std::string m_error = "not error";
std::vector <int> m_posPlayer(0);
std::vector <std::string> m_namePlayer(0);
std::vector <sf::IpAddress> m_addressPlayer(0);
std::string m_stringObstacle = "";
for (int i=0;i<80000;i++){
sprintf(number, "%d", m_obstacle[i]);
m_stringObstacle += std::string(number) + "+";
}
}
int Map::sendMap(sf::IpAddress address, unsigned short clientPort, sf::UdpSocket& socket){
std::string header = "rcv_map";
sf::Packet packet;
packet >> header >> m_stringObstacle;
if(socket.send(packet, address, clientPort)!=sf::UdpSocket::Done){
m_error += "Error sending the packet \n";
}
return 0;
}
int Map::error(){
if (m_error != "not_error"){
std::cout << "here is a following list of errors : " << m_error << std::endl;
}
m_error.erase(0,m_error.length());
}
Map.hpp:
#include <iostream>
#include "SFML/Network.hpp"
#ifndef DECODE_H_INCLUDED
#define DECODE_H_INCLUDED
class Map{
public:
Map();
int sendMap(sf::IpAddress address, unsigned short clientPort, sf::UdpSocket& socket);
int error();
private:
int m_obstacle;
std::vector <int> m_posPlayer;
std::vector <int> m_namePlayer;
std::vector <sf::IpAddress> m_addressPlayer;
std::string m_stringObstacle;
};
#endif // DECODE_H_INCLUDED
The problem probably exists in the headers, but I can't figure it out.
Problems are probably about headers, but can't find why.
That is absolutely right! You have applied inclusion guards incorrectly.
You have used the inclusion guard from a wrong hpp file:
#ifndef DECODE_H_INCLUDED
in map.hpp comes from decode.hpp. It should be
#ifndef MAP_H_INCLUDED
I think that the problem is related to these macro definitions in Map.hpp
#ifndef DECODE_H_INCLUDED
#define DECODE_H_INCLUDED
It seems they are the same definitions that are used in decode.hpp that is included before Map.hpp
Take into account that at least this constructor is wrong does not make sense and will not compile
Map::Map(){
int i = 0;
int m_obstacle[80000] = {0};
std::vector <int> m_posPlayer(0);
std::vector <std::string> m_namePlayer(0);
std::vector <sf::IpAddress> m_addressPlayer(0);
std::string m_stringObstacle = "";
for (i=0;i<80000;i++){
m_stringObstacle += m_obstacle[i] + "+";
}
}
These local objects
std::vector <int> m_posPlayer(0);
std::vector <std::string> m_namePlayer(0);
std::vector <sf::IpAddress> m_addressPlayer(0);
std::string m_stringObstacle = "";
are not used.
I think you mean class data members instead of the local objects.:)
And this statement
m_stringObstacle += m_obstacle[i] + "+";
is wrong and does not make sense.
Also data member
int m_obstacle;
is declared like a scalar object. You may not redeclare it in the constructor like an array.

Struct defined in header and included in two source codes is only defined in one

I have a struct defined in a header file with three other files that #include that header file. One is another header(queue.h) file that defines a very basic hash table and the other two are source codes where one is defining the functions from the hash table header(queue.cpp) and the other contains main(p2.cpp).
The problem that I'm having is that the struct seems to work fine in p2.cpp but in queue.h the compiler is telling me that the struct is undefined.
Here is p2.h containing the struct definition.
#ifndef __P2_H__
#define __P2_H__
#define xCoor 0
#define yCoor 1
#include <iostream>
#include <string>
#include "queue.h"
#include "dlist.h" //linked list which I know works and is not the problem
using namespace std;
struct spot {
float key[2];
string name, category;
};
#endif /* __P2_H__ */
I have queue.h included in this header so that I only have to include p2.h in p2.cpp.
Here is p2.cpp
#include <iostream>
#include <string>
#include <iomanip>
#include "p2.h"
using namespace std;
int main () {
cout << fixed;
cout << setprecision (4);
Queue hashTable;
spot *spot1 = new spot;
spot1->key[xCoor] = 42.2893;
spot1->key[yCoor] = -83.7391;
spot1->name = "NorthsideGrill";
spot1->category = "restaurant";
hashTable.insert(spot1);
Dlist<spot> test = hashTable.find(42.2893, -83.7391);
while (!test.isEmpty()) {
spot *temp = test.removeFront();
cout << temp->key[xCoor] << " " << temp->key[yCoor] << " " << temp->name << " " << temp->category << endl;
delete temp;
}
return 0;
}
Places and item in the hash table and takes it back out.
Here is queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <iostream>
#include <string>
#include "dlist.h"
#include "p2.h"
using namespace std;
class Queue {
// OVERVIEW: contains a dynamic array of spaces.
public:
// Operational methods
bool isEmpty();
// EFFECTS: returns true if list is empy, false otherwise
void insert(spot *o);
// MODIFIES this
// EFFECTS inserts o into the array
Dlist<spot> find(float X, float Y);
// Maintenance methods
Queue(); // ctor
~Queue(); // dtor
private:
// A private type
int numInserted;
int maxElts;
Dlist <spot>** queue;
// Utility methods
//Increases the size of the queue.
void makeLarger();
int hashFunc(float X, float Y, int modNum);
};
#endif /* __QUEUE_H__ */
Here is queue.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include "queue.h"
using namespace std;
bool Queue::isEmpty() {
return !numInserted;
}
void Queue::insert(spot *o) {
if (numInserted >= maxElts) {
makeLarger();
}
int index = hashFunc(o->key[xCoor], o->key[yCoor], maxElts);
queue[index] -> insertFront(o);
}
Queue::Queue() {
numInserted = 0;
maxElts = 1000;
queue = new Dlist<spot>*[maxElts];
for (int i = 0; i < maxElts; i++) {
queue[i] = new Dlist<spot>;
}
}
Queue::~Queue() {
for (int i = 0; i < maxElts; i++) {
delete queue[i];
}
delete[] queue;
}
void Queue::makeLarger() {
Dlist <spot>** temp = queue;
queue = new Dlist <spot>*[maxElts*2];
for (int i = 0; i < maxElts*2; i++) {
queue[i] = new Dlist<spot>;
}
for (int i = 0; i < maxElts; i++) {
while (!temp[i] -> isEmpty()) {
spot *spotTemp = temp[i] -> removeFront();
int index = hashFunc(spotTemp->key[xCoor], spotTemp->key[yCoor], maxElts*2);
queue[index] -> insertFront(spotTemp);
}
}
for (int i = 0; i < maxElts; i++) {
delete temp[i];
}
delete[] temp;
maxElts *= 2;
}
int Queue::hashFunc(float X, float Y, int modNum) {
return ((int)(10000*X) + (int)(10000*Y))%modNum;
}
Dlist<spot> Queue::find(float X, float Y) {
Dlist<spot> result;
Dlist<spot> *temp = new Dlist<spot>;
int index = hashFunc(X, Y, maxElts);
while (!queue[index] -> isEmpty()) {
spot *curSpot = queue[index] -> removeFront();
if ((curSpot->key[xCoor] == X) && (curSpot->key[yCoor] == Y)) {
result.insertFront(new spot(*curSpot));
}
temp -> insertFront(curSpot);
}
delete queue[index];
queue[index] = temp;
return result;
}
I believe that the problem is in my queue.h file because it's where I get all of the errors like "spot has not been declared". Every time spot appears in queue.h I have at least one error. I searched around for anything like this but all I could find was people trying to share one instance of a struct across multiple source files, or the obvious question of putting a struct in a header and including that header across multiple source files(which is what I'm doing but my problem seems to be a rather unique one).
You are including queue.h within the header that actually defines spot, so by the point the file is actually included spot has not been defined yet.
For your scope guards, note that identifiers starting with a double underscore are reserved by the implementation, don't use them.
And this is a poor choice even in plain C:
#define xCoor 0
#define yCoor 1
use this instead:
enum {
xCoor = 0
, yCoor = 1
};
Ok first never ever using "using" clauses in header files (it destroys the purposes of namespaces)
2nd provide a complete example that fails to compile
In addition to what others have said, you also have a circular reference error, which can also lead to similar undefined symbol errors. You have queue.h include p2.h, which includes queue.h.