I have 1 header file and 2 .cpp files (I've included main.cpp) and work on CodeBlocks. My problem is that compiler not see the errors in the second .cpp file (graph_interface.cpp) when I build it. Do you have any suggestions? Where am I going wrong?.
Simply I get the output even I did the wrong thing in graph_implementation.cpp file:
Target is up to date.
Nothing to be done (all items are up-to-date).
For example, my code in main.cpp
//main.cpp
#include "graph_interface.h"
int main(int argc,char *argv[])
{
return 0;
}
graph_interface.h file
#ifndef GRAPH_INTERFACE_H_INCLUDED
#define GRAPH_INTERFACE_H_INCLUDED
typedef struct{int v;int w;} Edge;
Edge EDGE(int,int);
typedef struct graph *Graph;
Graph GRAPHinit(int);
void GRAPHinsertE(Graph,Edge);
void GRAPHremoveE(Graph,Edge);
int GRAPHedges(Edge[],Graph G);
Graph GRAPHcopy(Graph);
void GRAPHdestroy(Graph);
#endif // GRAPH_INTERFACE_H_INCLUDED
And other cpp file graph_implementation.cpp
#include "graph_interface.h"
using namespace std;
struct graph{
int V;
int E;
int **adj;
};
Graph GRAPHinit(int V){
Graph G=malloc(sizeof *G);
G->V=V;
G->E=0;
G->adj=MATRIXint(V,V,0);
return G;
;// not give anything
}
If you're expecting the line:
;// not give anything
to produce an error, the reason you aren't seeing one is because empty statements are perfectly legal in C++; This line does not contain any error.
// complete, legal C++ program
int main() {
;
}
Using new/delete or malloc/free this way goes against modern C++ practice because it's very difficult to do correctly. Modern practice would be more like:
class Graph {
int V;
Matrix adj;
public:
Graph(int V)
: V(V), adj(V*V, 0)
{}
}
int main() {
Graph g; // automatically initialized and destroyed correctly
// ...
}
Related
I have 3 files
dimentions.h:
namespace mtm {
class Dimensions {
int row, col;
//some code
};
}
IntMatrix.h:
#include "dimentions.h"
namespace mtm
{
class intMatrix
{
private:
int** data;
int col;
int row;
public:
intMatrix(Dimensions dims, int num=0);
//some code
};
//the line bellow is where I get the error
intMatrix(Dimensions dims, int num=0): col(dims.getCol()),row(dims.getRow()) ,data(new int*[dims.getRow()])
{
for(int i=0;i<dims.getCol())
{
data[i](new int[dims.getCol]);
}
for(int i=0;i<dims.getRow();i++)
{
for(int j=0;j<dims.getCol();j++)
{
data[i][j]=num;
}
}
}
}
the compiler says: expected ‘)’ before ‘dims’
and when I put the mouse at dims, vs code says: " error-type mtm::dims"
but dims is not a type it is a vriable.
IntMatrix.cpp:
#include "IntMatrix.h"
using namespace mtm;
//some code
in IntMatrix.cpp the problem is that it doesn't recognize what Dimentions is , however it does recognize what intMatrix is.
Welcome to StackOverflow!
Compiler messages are sometimes misleading, and in your case you have an error because you are repeating the default value in your implementation. This is probably the error the compiler is complaining about.
EDIT
As pointer out by drescherjm, you also forgot the add the class name to the constructor
The correct definition should be :
intMatrix::intMatrix(Dimensions dims, int num): ...
Please let me know if you still have the error after that.
In your C++ source code the constructor must be defined as
intMatrix::intMatrix(Dimensions dims, int num) ....
So you have two mistakes: you have to add intMatrix and delete =0
But do not ever write a matrix class like this. This is terrible C++ code. You should never need to call new directly. And your data, in this case, is laid down very cache unfriendly
In C++, it is sometimes considered good practice to declare your classes in a header file and define all the methods in a cpp file. I understand this, but a consequence of this seems to be that instead of having all of the class methods tabbed-in inside curly braces, they are just out in the open in the cpp file. Is there any way to group the methods of a class together in the cpp file while still declaring them in a header file? I like being able to collapse things in my IDE... I'd just get over it, but it's been a while since I've coded anything in C++ and I'm wondering if there's a way to do it that I just forgot about.
To be clear what I mean, here's an example:
test.h:
class Testing {
public:
Testing(int x);
void print();
int x;
};
test.cpp:
#include <iostream>
#include "test.h"
using namespace std;
// class Testing {
// public:
// Testing(int x){
// this->x = x;
// }
// void print(){
// cout << this->x << endl;
// }
// };
Testing::Testing(int x){
this-> x = x;
}
void Testing::print(){
cout << this->x;
}
int main(){
Testing t(100);
t.print();
}
I'd like to do what is commented above in test.cpp instead, but that doesn't work, right? (I think it'd be like declaring a new class distinct from the one in the header file?)
You could do this:
== h.h ==
namespace H_DEFS {
class H {
public:
int A();
int B();
};
}
using namespace H_DEFS;
== h.cpp file ==
#include "h.h"
namespace H_DEFS {
int H::A() { return 4;};
int H::B() { return 5;};
}
== main.cpp ==
#include "h.h"
int main() {
return H().A() + H().B();
}
but it's a weird idiom for other programmers to read just for the benefit of your IDE.
I have a weightedDirectedGraph class and a vertex class in their own header file, weightedDirectedGraph.h. This is it:
#ifndef GRAPH
#define GRAPH
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include "minHeapVertex.h"
using namespace std;
class vertex
{
public:
string data;
list<vertex *> neighbors;
bool known;
int distance, id;
vertex * path;
vertex(string x)
{
data = x;
}
};
class weightedDirectedGraph
{
private:
list<vertex *> vertexList;
vector<vector<int> > edgeWeights; //2D vector to store edge weights
int idCount;
weightedDirectedGraph()
{
idCount = 0;
}
vertex * findVertex(string s);
void dijkstrasAlg(vertex * s);
public:
void addVertex(string x);
//adds bi-directional edges
void addWeightedEdge(string x, string y, int weight);
};
#endif
And I have a minHeapVertex class in a minHeapVertex.h file that will be used as a priority queue in Dijkstra's algorithm. This is the file:
#ifndef MIN_HEAP_VERTEX
#define MIN_HEAP_VERTEX
#include <iostream>
#include <vector>
#include "weightedDirectedGraph.h"
using namespace std;
class minHeapVertex
{
public:
explicit minHeapVertex(int capacity = 100)
:heapArray(capacity + 1), currentSize{ 0 } {}
bool isEmpty() const
{
return (currentSize == 0);
}
vertex * getMinVertex() const; //getting C2143 error here that says I'm missing a semi-colon before '*'. Doesn't make sense though.
void insert(vertex * insertItem);
void deleteMin();
vertex * deleteAndReturnMin();
void makeEmpty()
{
currentSize = 0;
}
void decreaseKey(int index, int decreaseValue);
void remove(int index);
private:
void buildHeap();
void percolateDown(int hole);
vector<vertex *> heapArray;
int currentSize;
};
#endif
I"m getting a lot of compiling errors (with the first one being a C2143 error on the getMinVertex() declaration) and I think it may have something do with trying to access the vertex class in minHeapVertex.h. Can someone show me what I'm doing wrong? Been at it for hours, tried forward declaring the vertex class, tried removing some of the includes "", looked up the error codes and changed things, but nothing is working and just end up with a bunch of errors.
Problem:
OP has a circular dependency between minHeapVertex.h and weightedDirectedGraph.h.
Solution:
Eliminate the dependency.
minHeapVertex.h defines minHeapVertex. minHeapVertex requires vertex.
weightedDirectedGraph.h defines vertex and weightedDirectedGraph. Neither require minHeapVertex.
Three possibilities at this point:
Spin vertex off into its own vertex.h header. minHeapVertex.h and weightedDirectedGraph.h both include vertex.h and not each other.
weightedDirectedGraph.h does not require minHeapVertex.h, so remove #include "minHeapVertex.h" from weightedDirectedGraph.h to break the circle.
forward definition of class vertex; in minHeapVertex.h and the removal of #include "weightedDirectedGraph.h" from minHeapVertex.h.
Solution 1 is preferred. Giving vertex its own header may prevent future problems. 2 is easiest to implement. 3 is pretty stupid and not recommended.
Why circular dependency prevented minHeapVertex from seeing vertex:
To make this easier to see, I've removed all of the other includes from the header files.
Here's my idiotic little test.cpp
#include "weightedDirectedGraph.h"
int main(int argc, char * argsv[])
{
return 0;
}
The compiler will make a little temp file of test.cpp. It will then start parsing until it finds an include directive. The included file is copy-pasted into the temp file at the include statement. So the temp file looks sort of like this:
#define GRAPH
#include "minHeapVertex.h"
using namespace std;
class vertex
{
public:
string data;
list<vertex *> neighbors;
bool known;
int distance, id;
vertex * path;
vertex(string x)
{
data = x;
}
};
class weightedDirectedGraph
{
private:
list<vertex *> vertexList;
vector<vector<int> > edgeWeights; //2D vector to store edge weights
int idCount;
weightedDirectedGraph()
{
idCount = 0;
}
vertex * findVertex(string s);
void dijkstrasAlg(vertex * s);
public:
void addVertex(string x);
//adds bi-directional edges
void addWeightedEdge(string x, string y, int weight);
};
int main(int argc, char * argsv[])
{
return 0;
}
The compiler parses down a little further and sees the include of minHeapVertex.h and copy-pastes so you get this:
#define GRAPH
#define MIN_HEAP_VERTEX
#include "weightedDirectedGraph.h"
using namespace std;
class minHeapVertex
{
public:
explicit minHeapVertex(int capacity = 100)
:heapArray(capacity + 1), currentSize{ 0 } {}
bool isEmpty() const
{
return (currentSize == 0);
}
vertex * getMinVertex() const; //getting C2143 error here that says I'm missing a semi-colon before '*'. Doesn't make sense though.
void insert(vertex * insertItem);
void deleteMin();
vertex * deleteAndReturnMin();
void makeEmpty()
{
currentSize = 0;
}
void decreaseKey(int index, int decreaseValue);
void remove(int index);
private:
void buildHeap();
void percolateDown(int hole);
vector<vertex *> heapArray;
int currentSize;
};
using namespace std;
class vertex
{
public:
string data;
list<vertex *> neighbors;
bool known;
int distance, id;
vertex * path;
vertex(string x)
{
data = x;
}
};
class weightedDirectedGraph
{
private:
list<vertex *> vertexList;
vector<vector<int> > edgeWeights; //2D vector to store edge weights
int idCount;
weightedDirectedGraph()
{
idCount = 0;
}
vertex * findVertex(string s);
void dijkstrasAlg(vertex * s);
public:
void addVertex(string x);
//adds bi-directional edges
void addWeightedEdge(string x, string y, int weight);
};
int main(int argc, char * argsv[])
{
return 0;
}
That gets parsed down to #include "weightedDirectedGraph.h", but fortunately GRAPH has been defined, so most of weightedDirectedGraph.h gets left out. If it hadn't, Everything in weightedDirectedGraph.h would have been defined again and minHeapVertex.h would once again been included over and over and eventually the compiler would crash or tell you to expletive deleted off with a politely worded error message.
Anyway, we can already see what's gone wrong in the above code trace: minHeapVertex needs to know type vertex, but that won't be defined for another 20 lines or so.
If test.cpp had been written as
#include "minHeapVertex.h"
int main(int argc, char * argsv[])
{
return 0;
}
The header files would have been included in the other order and it would have compiled, giving a false sense of security until one day you wrote a program that included weightedDirectedGraph.h first. In other words, the library works until it doesn't, and you didn't change a line of the library's code. Have fun pulling your hair out.
Avoid circular dependencies, circular references and circular saws. All three can rip you up pretty bad.
On to using namespace std; This evil little shortcut takes EVERYTHING in the std namespace and adds it to the global namespace. If you had a function named reverse, now you have to deal with potential overload conflicts with std::reverse. The standard library is huge. There are a huge number of function, class, and variable names that are just itching to overload, override and just plain trample your stuff.
But that's your problem.
Putting using namespace std; in a header make it everyone's problem. Anyone who uses your graphing library has to wade through a minefield, and unless they take a close look at your header file and see that declaration they won't have the slightest clue.
Longer discussion can be found here. Either explicitly namespace everything (std::vector, std::string, ...) or pull in only the pieces you need and know will not conflict with your code with using. Eg:
using std::vector;
using std::string;
Do not put this in your header or someone may wind up wonder why their homebrew vector is freaking out. Probably shouldn't be homebrewing vectors, but you can't save everybody.
I'm new in C++ and I have something to do with a linked list, and I don't know why it doesn't work, need help from a prof :O)
Here's my .h
#ifndef UnCube_H
#define UnCube_H
using namespace std;
class ACube{
public:
ACube();
struct Thecube;
private:
void PrintList();
};
#endif
My ACube.cpp
#include <iostream>
#include "ACube.h"
ACube::ACube(){
};
struct Thecube{
int base;
int cube;
Thecube * next ;
};
void ACube::PrintList(){
};
and finally my main.cpp
#include <cstdlib>
#include <iostream>
#include "ACube.h"
using namespace std;
int main()
{
ACube * temp;
temp = (ACube*)malloc(sizeof(ACube));
for (int inc=1; inc <=20 ; inc++){
temp->ACube->nombrebase = inc;
temp->cube = inc*inc*inc;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Everything was working fine, but when I add these lines :
temp->ACube->nombrebase = inc;
temp->cube = inc*inc*inc;
I add error saying :
'class ACube' has no member named 'TheCube'
'class ACube' has no member named 'cube'
Can someone help me because I want to create my list and fill the cube with number.
Other thing I want to use THIS. in the print,
Maybe someone can teach me what's wrong and how to do it !
Thanks for any help
You don't need to have a struct inside your class.
#ifndef UnCube_H
#define UnCube_H
using namespace std;
class ACube{
public:
ACube();
int base;
int cube;
ACube * next ;
private:
void PrintList();
};
#endif
ACube.cpp
#include <iostream>
#include "ACube.h"
ACube::ACube(){
};
void ACube::PrintList(){
};
Also, this string is wrong:
temp->ACube->nombrebase = inc;
it should be just:
temp->base = inc;
Last but not least, this code doesn't create a linked list, because you don't do anything with the ACube::next pointer.
There are so many horrible problems in your code, I suggest you should learn more C++ knowledge before writing linked list.
1. What is nombrebase?
I think nobody can answer.
2. You must allocate C++ class by new key word instead of malloc.
new invokes not only allocation but also class constructor, while malloc allocates only.
3. Thecube should been defined inside ACube
Since the code in your main() refers the member cube in class Thecube, main() must know what it is.
4. The member next in class ACube is a pointer which points to what?
What does a pointer point to without initilization? You should initial it in constructor, and destroy it in destructor.
5. temp->ACube
ACube is a class type, you can access member object, but not a type.
6. Never using namespace into a header file
It would make the client of header file has name collision.
The following is the corrected code. Just no compile error and runtime error, but this is NOT linked list:
ACube.h
#ifndef UnCube_H
#define UnCube_H
class ACube{
public:
struct Thecube
{
int base;
int cube;
Thecube * next;
};
ACube();
~ACube();
Thecube *next;
private:
void PrintList();
};
#endif
ACube.cpp
ACube::ACube()
: next(new Thecube)
{
}
ACube::~ACube()
{
delete next;
}
void ACube::PrintList(){
}
main.cpp
#include <cstdlib>
#include <iostream>
#include "ACube.h"
using namespace std;
int main()
{
ACube * temp;
temp = new ACube;
for (int inc = 1; inc <= 20; inc++)
{
temp->next->base = inc; // <-- This is not linked list, you shall modify.
temp->next->cube = inc*inc*inc; // <-- This is not linked list, you shall modify.
}
system("PAUSE");
return EXIT_SUCCESS;
}
Hi I am trying to understand the scope of friend functions and I get a "not declared in scope" error. Here is my code:
//node.h
class Node{
public:
int id;
int a;
int b;
friend int add(int,int);
void itsMyLife(int);
Node();
};
//node.cpp
Node::Node(){
a=0;
b=0;
id=1;
}
void Node::itsMyLife(int x){
cout<<"In object "<<id<<" add gives "<<add(x,a)<<endl;
}
//routing.cpp
#include "node.h"
int add(int x, int y){
return x+y;
}
//main.cpp
#include "node.h"
int main(){
return 0;
}
I get the error "add not declared in this scope" in node.cpp. Why do I get this error when I have declared the function in the class scope? Any help will be appreciated. Thanks
Inside your node class you declare a friend function int add (int, int). However, currently the compiler hasn't encountered the function yet and therefore it is unknown.
You could make a separate header and source file for your add function. Then in node.h include you new header. Because in the file where you declare Node the function add is not known currently.
So you might make a add.h and a add.cpp file for example and include add.h before declaring Node. Don't forget to compile add.cpp as well.
Its a bug on the the Linux side. The code should work. I have code right now that compiles fine on the Windows side and when I move it to the Linux side I get the same error. Apparently the compiler that you are using on the Linux side does not see/use the friend declaration in the header file and hence gives this error.
By simply moving the of the friend function's implementation in the C++ file BEFORE that function's usage (e.g.: as might be used in function callback assignment), this resolved my issue and should resolve yours also.
Best Regards
You haven't actually declared the function.
extern int add(int, int);
#include "node.h"
#include <iostream>
using namespace std;
class Node{
public:
int id;
int a;
int b;
friend int add(Node &a);
void itsMyLife(int);
Node();
};
//node.cpp
Node::Node(){
a=0;
b=0;
id=1;
}
void Node::itsMyLife(int x):b(x){
cout<<"In object "<<id<<" add gives "<<add(Node &a)<<endl;
}
//routing.cpp
#include "node.h"
int add(Node &a){
return a.b+a.y;
}
//main.cpp
int main(){
Node n;
n.ItsMyLife(15);
cout<<add(n);
return 0;
}
This should work fine - I guess. The syntax for "friend" function is -- friend {returntype} {functionname} (class_name &object_name). To access any of the members of the class use object_name.variable_name.