I read that "if you declare and implement a function in a header file (Header.h) and if this file gets included twice, then you'll most likely will get a function already defined error at some point.". But in my code all the functions that I get errors on are in a .cpp file.
List.h
#pragma once
typedef struct list
{
int lin;
int col;
int val;
struct list* next;
struct list* prev;
}list;
List.cpp
#include "List.h"
bool empty(list*& start)
{
return (start == nullptr);
}
Matrice.h
#pragma once
#include "List.h"
class Matrice
{
private:
list* start;
list* finish;
public:
Matrice() :start(nullptr), finish(nullptr) {}
Matrice(const Matrice& matrice);
};
Matrice.cpp
#include "Matrice.h"
#include "List.cpp"
Matrice::Matrice(const Matrice& matrice)
{
if (empty(start))
{
// Code
}
}
Source.cpp
#include "Matrice.h"
#include <iostream>
int main()
{
Matrice a;
Matrice b;
a = b;
}
I added all the files, maybe there's something I don't see. The error is on the bool empty(list*& start) function ("already defined in List.obj").
You have an #include<List.cpp> in your Matrice.cpp and as you compile and link all cpp files together this will result duplicate definitions of everything defined in List.cpp as they are also defined in Matrice.cpp due to the include.
Replace the #include<List.cpp> with #include<List.h> and add the declaration of empty into the List.h
Related
I have a simple c++ app:
node.h:
#include<iostream>
using namespace::std;
class Node
{
private:
int data;
Node *next;
public:
Node(int nodeData,Node *nextNode);
};
node.cpp:
#include "node.h"
Node::Node(int nodeData, Node *nextNode) {
data = nodeData;
next = nextNode;
}
linked_list.h
#include "node.h"
class LinkedList
{
private:
Node *head;
Node *tail;
int size;
public:
LinkedList();
int getSize();
};
linked_list.cpp:
#include "linked_list.h"
LinkedList::LinkedList()
{
size = 0;
}
int LinkedList::getSize() {
return size;
}
main.cpp:
#include <iostream>
#include "node.h"
#include "linked_list.h"
using namespace ::std;
int main()
{
cout << "This is main!\n";
return 0;
}
I am on linux, inside the projcet's directory, I open a terminal there and try to compile them by this command:
g++ *.cpp *.h -o app
but I get this error:
In file included from linked_list.h:1:0,
from main.cpp:3:
node.h:1:7: error: redefinition of ‘class Node’
class Node
^~~~
In file included from main.cpp:2:0:
node.h:1:7: note: previous definition of ‘class Node’
class Node
^~~~
I looked at some posts here on stackoverlfow but had no luck in solving my problem. I am new to c++, I know that the compiler thinks I am redefining class Node somewhere, but where is this somewhere so I can remove the definition?
Your linked_list.h includes node.h, so the compiler will see the definition in node.h twice while compiling main.cpp.
To avoid this problem, you should add "include guard" to your header files.
It should be like this:
node.h:
#ifndef NODE_H_GUARD // add this
#define NODE_H_GUARD // add this
#include<iostream>
using namespace::std;
class Node
{
private:
int data;
Node *next;
public:
Node(int nodeData,Node *nextNode);
};
#endif // add this
The macro name to define and check should be different for each headers.
Another way to avoid this problem is to adding #pragma once as the first lines of your headers if your compiler supports this.
I am implementing bptree using c++. I am am stuck in the initial step of node creation. Keep getting "C2011 'Node':'class' type redefinition" error. I found some suggestions online to remove class key word from cpp file. But when I remove class keyword I get lots of other errors. here is my code for Node.cpp:
#include "Node.h"
#include <cstdio>
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Node {
bool leaf;
Node** kids;
map<int, string> value;
int keyCount;//number of current keys in the node
//constructor;
Node::Node(int order) {
this->value = {};
this->kids = new Node *[order + 1];
this->leaf = true;
this->keyCount = 0;
for (int i = 0; i < (order + 1); i++) {
this->kids[i] = NULL;
}
}
};
and Node.h file is as following:
#pragma once
#ifndef NODE_HEADER
#define NODE_HEADER
class Node {
public:
Node(int order) {};
};
#endif
How can I fix this?
Problem
In C++, headers are simply pasted into the body when you #include. So now the compiler sees:
class Node {
public:
Node(int order) {};
};
// stuff from system headers omitted for brevity
using namespace std;
class Node {
bool leaf;
//...
};
There are two problems here:
compiler sees class Node twice with different bodies.
Node::Node is defined twice (first time empty {}).
Solution
The header should include class declaration:
#include <map>
using namespace std;
class Node {
bool leaf;
Node** kids;
map<int, string> value;
int keyCount;//number of current keys in the node
//constructor;
Node(int order);
};
Note that the constructor has no body here. It's just a declaration. Because it uses map you need to include <map> and add using namespace before the declaration.
After that don't put class Node again in the .cpp or .cc file. Only put the method implementations at the top level:
Node::Node(int order) {
// ...
}
I started building a project on my computer. the project compiled on my computer, but when i copied it to another computer it had fatal errors(its work on visual c++ express 2010). its still small so i will just copy all the project.
source file->main.cpp:
#include <iostream>
#include <string>
using namespace std;
#include "List.h"
void products_menu(){
return;
}
void stores_menu(){
return;
}
void costumers_menu(){
return;
}
int main(){
int option;
Products a;
do{
cin>>option;
if(option==1)
products_menu();
//option funcion
if(option==2)
stores_menu();
//option funcion
if(option==3)
costumers_menu();
//option funcion
}while(option!=4);
}
source file->List.cpp:
#include <iostream>
#include <string>
using namespace std;
#include "List.h"
void products_menu(){
return;
}
void stores_menu(){
return;
}
void costumers_menu(){
return;
}
int main(){
int option;
Products a;
do{
cin>>option;
if(option==1)
products_menu();
//option funcion
if(option==2)
stores_menu();
//option funcion
if(option==3)
costumers_menu();
//option funcion
}while(option!=4);
}
Header files->List.h:
#pragma once
#ifndef LIST_H
#define LIST_H
#include <string>
using namespace std;
class Products{
private:
typedef struct node{
int id;
string name;
int price;
node* next;
};
//typedef struct node* nodePtr;
//nodePtr head;
public:
Products();
//~Products();
void addProduct(int id, string& name, int price);
void updateNameProduct(int id, string& oldName, string& newName);
void updatePriceProduct(int id, int oldPrice, int newPrice);
void printProducts();//
};
Products* first;
Products* nodePtr;
#endif
and this is the errors it gives me:
error LNK2005: "class Products * nodePtr" (?nodePtr##3PAVProducts##A) already defined in List.obj
error LNK2005: "class Products * first" (?first##3PAVProducts##A) already defined in List.obj
error LNK1169: one or more multiply defined symbols found
If you must use global variables (which is usually a bad idea), then you can't define them in a header. They're subject to the One Definition Rule, so can only have a definition in one source file.
Declare them in the header:
extern Products* first;
and define them in a source file:
Products* first;
But it sounds like you want something more like the commented out declarations: a pointer to the first node, as a member of the Products class, with no strange global variables.
The code works fine before I split it into two files with board.h and board.cpp
board.h is given by
#ifndef BOARD_H
#define BOARD_H
#include "Graph.h"
#include "ShortestPath.h"
using namespace std;
enum class boardType : short{SEVEN, ELEVEN};
enum class nodeType : short{UNDEFINED, HUMAN, COMPUTER };
char status2char(nodeType a);
class board{
public:
board{
...
}
~board(){
delete []HexBoard;
}
void printBoard(){
...
}
bool setComputerPosition(int i, char a);
bool setHumanPosition(int i, char a);
private:
nodeType *HexBoard;
Graph Computer;
Graph Human;
int boardSize;
};
#endif /* BOARD_H*/
The board.cpp is like follows;
#include "board.h"
char status2char(nodeType a){
...
}
bool board::setComputerPosition(int i, char a){
...
}
bool board::setHumanPosition(int i, char a){
...
}
All head files have include guards, and the error says the constructor in shortestGraph.h(which is another class) is redefined.
Could you please help me find the problem? Thanks a lot.
I'm trying to implement a tree-like structure with two classes: Tree and Node. The problem is that from each class I want to call a function of the other class, so simple forward declarations are not enough.
Let's see an example:
Tree.h:
#ifndef TREE_20100118
#define TREE_20100118
#include <vector>
#include "Node.h"
class Tree
{
int counter_;
std::vector<Node> nodes_;
public:
Tree() : counter_(0) {}
void start() {
for (int i=0; i<3; ++i) {
Node node(this, i);
this->nodes_.push_back(node);
}
nodes_[0].hi(); // calling a function of Node
}
void incCnt() {
++counter_;
}
void decCnt() {
--counter_;
}
};
#endif /* TREE_20100118 */
Node.h:
#ifndef NODE_20100118
#define NODE_20100118
#include <iostream>
//#include "Tree.h"
class Tree; // compile error without this
class Node
{
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id) : tree_(tree), id_(id)
{
// tree_->incCnt(); // trying to call a function of Tree
}
~Node() {
// tree_->decCnt(); // problem here and in the constructor
}
void hi() {
std::cout << "hi (" << id_ << ")" << endl;
}
};
#endif /* NODE_20100118 */
Calling Tree:
#include "Tree.h"
...
Tree t;
t.start();
This is just a simple example to illustrate the problem. So what I want is calling a function of Tree from a Node object.
Update #1: Thanks for the answers. I tried to solve the problem like in Java, i.e. using just one file per class. It seems I will have to start separating .cpp and .h files...
Update #2: Below, following the hints, I pasted the complete solution too. Thanks, problem solved.
In the headers, forward declare the member functions:
class Node
{
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id);
~Node();
void hi();
};
In a separate .cpp file that includes all the required headers, define them:
#include "Tree.h"
#include "Node.h"
Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
{
tree_->incCnt();
}
Node::~Node()
{
tree_->decCnt();
}
etc
This also has the effect of keeping your headers readable, so it is easy to see a class's interface at a glance.
Following the hints, here is the complete solution.
Tree.h:
#ifndef TREE_20100118
#define TREE_20100118
#include "Node.h"
#include <vector>
class Tree
{
int counter_;
std::vector<Node> nodes_;
public:
Tree();
void start();
void incCnt();
void decCnt();
};
#endif /* TREE_20100118 */
Tree.cpp:
#include "Tree.h"
#include "Node.h"
Tree::Tree() : counter_(0) {}
void Tree::start()
{
for (int i=0; i<3; ++i) {
Node node(this, i);
this->nodes_.push_back(node);
}
nodes_[0].hi(); // calling a function of Node
}
void Tree::incCnt() {
++counter_;
}
void Tree::decCnt() {
--counter_;
}
Node.h:
#ifndef NODE_20100118
#define NODE_20100118
class Tree;
class Node
{
Tree * tree_;
int id_;
public:
Node(Tree * tree, int id);
~Node();
void hi();
};
#endif /* NODE_20100118 */
Node.cpp:
#include "Node.h"
#include "Tree.h"
#include <iostream>
Node::Node(Tree * tree, int id) : tree_(tree), id_(id)
{
tree_->incCnt(); // calling a function of Tree
}
Node::~Node() {
tree_->decCnt();
}
void Node::hi() {
std::cout << "hi (" << id_ << ")" << std::endl;
}
The definition of Tree requires the definition of Node but not the other way around so your forward declaration is correct.
All that you have to do is removed the definition of any functions that require a full definition of Tree from the Node class body and implement them in a .cpp file where full definitions of both classes are in scope.
Can you but the constructor/destructor bodies in a .cxx file? You could include Tree.h there.