FIXED: had the method twice in the header file
I get the following error when trying to compile my project
% make
g++ -o p4 testTree.o tree.o node.o check.o
Undefined first referenced
symbol in file
Tree::inTree(int) tree.o
ld: fatal: Symbol referencing errors. No output written to p4
collect2: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target `p4'
Makefile
p4: testTree.o tree.o node.o check.o
g++ -o p4 testTree.o tree.o node.o check.o
testTree.o: testTree.cc tree.h node.h check.h
g++ -c -Wall -Werror testTree.cc
tree.o: tree.h tree.cc node.h check.h
g++ -c -Wall -Werror tree.cc
node.o: node.h node.cc check.h
g++ -c -Wall -Werror node.cc
check.o: check.h check.cc
g++ -c -Wall -Werror check.cc
clean:
rm -f *~ *.o p4
Relevant code from tree.cc and tree.h:
tree.cc
...
bool Tree::inTree(int k) const
{
return locate(k,root) != NULL;
}
...
tree.h
#ifndef TREE_H
#define TREE_H
#include "node.h"
#include "check.h"
using namespace std;
class Tree
{
private:
Node *root;
public:
Tree();
Tree(const Tree & t);
const Tree & operator=(const Tree &t);
friend ostream & operator<<(ostream &out, const Tree &t);
bool inTree(int k) const;
double & operator[](int k);
double & operator[](int k) const;
~Tree();
bool inTree(int index);
private:
Node * locate(int k, Node *rt) const;
ostream & display(ostream &out, Node *r, int dir=Node::L) const;
void add(int k, Node*&r);
void kill(Node *&rt);
void copy(Node *rt, Node *&newRt);
};
#endif
I get the feeling that it's something really simple, but I can't seem to figure it out.
The message you are getting actually comes from the linker, not from the compiler.
One of your member functions, bool Tree::inTree(int index);, is correctly declared and defined as a const member function:
// Declaration in tree.h
bool inTree(int index) const;
// Definition in tree.cc
bool Tree::inTree(int k) const
// ^^^^^
However, in tree.h you also define this non-const overload of inTree():
// Declaration in tree.h, definition (supposedly) nowhere
bool Tree::inTree(int k)
For which no definition is provided. This is what the linker complains about.
Here is your error:
bool Tree::inTree(int k) const
{
return locate(k,root) != NULL;
}
in your .h you define
bool inTree(int);
This is a difference!
Related
For a exercise in C++, I must to use a protected c++ in a function which overload the operator <<.
But we know that protected function is accessible in a class or with the keyword friend if we want to define the function in a cpp file.
For the moment, I have one abstract class and the main.
I dont't have any idea how I can to fix this error, and I wanted to finish as far as possible this exercice early ;)
Card.hpp
#ifndef CARD_HPP
#define CARD_HPP
#include <string>
#include <iostream>
class Card
{
std::string name;
protected:
virtual std::ostream & toStream(std::ostream & out){out << name;return out;}
public:
Card(std::string n):name(n){}
friend std::ostream & operator<<(std::ostream & out, const Card &c);
};
#endif
Card.cpp
#include <Card.hpp>
std::ostream & operator<<(std::ostream & out, const Card &c)
{
return c.toStream(out);
}
main.cpp
#include <Card.hpp>
using namespace std;
int main()
{
Card card("montain");
cout << card << "\n";
return 0;
}
Output
clang++ -Wall -std=c++14 -c -o obj/main.o src/main.cpp -I include
clang++ -Wall -std=c++14 -c -o obj/Card.o src/Card.cpp -I include
src/Card.cpp:5:12: error: member function 'toStream' not viable: 'this' argument has type 'const Card', but function is not
marked const
return c.toStream(out);
^
include/Card.hpp:12:32: note: 'toStream' declared here
virtual std::ostream & toStream(std::ostream & out){out << name;return out;}
^
1 error generated.
makefile:16: recipe for target 'obj/Card.o' failed
make: *** [obj/Card.o] Error 1
The makefile
CC = clang++
CFLAGS = -Wall -std=c++14
HDIR = include
ABSTRACT = obj/Card.o
.PHONY: doc
compile: bin/main
./bin/main
bin/main: obj/main.o ${ABSTRACT}
${CC} ${CFLAGS} -o $# $^
obj/%.o: src/%.cpp
${CC} ${CFLAGS} -c -o $# $< -I ${HDIR}
doc:
doxygen Doxyfile
clean:
rm obj/*.o
rm bin/*
cleanDoc:
rm doc/* -rf
The problem is not that the function is protected, but that it is not const.
src/Card.cpp:5:12: error: member function 'toStream' not viable: 'this' argument has type 'const Card', but function is not
marked const
return c.toStream(out);
As the error message says, c is const due to const Card &c, and as of that you can only call const member functions on c.
So either make your toStream member function const:
virtual std::ostream & toStream(std::ostream & out) const
Or change the streaming operator so that c is not const. But that's not recommended, you should only pass as non const ref if the function is expected to change/replace the passed argument:
std::ostream & operator<<(std::ostream & out, Card &c)
I'm trying to develop a neural network in c++.
I refactored my code utilizing class-inheritance, to allow me to have different kinds of layers, whose neurons could be iterated over in sequence.
My problem is, that my linker (ld invoked by g++) complaines about undefined references to vtables and typeinfo-objects.
As far as I know, the error "undefined reference to vtable for class" comes from not implemented pure virtual methods in base classes, but unfortunately I not was able locate the error more percisely.
make all:
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Test2dSparselyNeuralNet.o Test2dSparselyNeuralNet.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o NeuralNet.o NeuralNet.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Sparsely2dNeuralNetwork.o Sparsely2dNeuralNetwork.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Connection.o Connection.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Layer2d.o Layer2d.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Neuron2dIterator.o Neuron2dIterator.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o input/2dinput/cross/cross.o input/2dinput/cross/cross.cpp
g++ -o bin/neural_net_2d Test2dSparselyNeuralNet.o NeuralNet.o Sparsely2dNeuralNetwork.o Connection.o Layer2d.o Neuron2dIterator.o input/2dinput/cross/cross.o
Layer2d.o: In function `Layer::Layer()':
Layer2d.cpp:(.text._ZN5LayerC2Ev[_ZN5LayerC5Ev]+0x13): undefined reference to `vtable for Layer'
Layer2d.o: In function `Iterator::Iterator()':
Layer2d.cpp:(.text._ZN8IteratorC2Ev[_ZN8IteratorC5Ev]+0xf): undefined reference to `vtable for Iterator'
Layer2d.o: In function `Layer::~Layer()':
Layer2d.cpp:(.text._ZN5LayerD2Ev[_ZN5LayerD5Ev]+0x13): undefined reference to `vtable for Layer'
Layer2d.o:(.rodata._ZTI7Layer2d[_ZTI7Layer2d]+0x10): undefined reference to `typeinfo for Layer'
Neuron2dIterator.o:(.rodata._ZTI16Neuron2dIterator[_ZTI16Neuron2dIterator]+0x10): undefined reference to `typeinfo for Iterator'
collect2: error: ld returned 1 exit status
make: *** [neural_net_2d] Error 1
makefile:
CXXFLAGS = -Wall -fmessage-length=0 --std=c++11 -w
CXXFLAGS_DEBUG = -g -Wall -fmessage-length=0 --std=c++11 -w
SAMPLES = input/2dinput/cross/cross.o
OBJS = Test2dSparselyNeuralNet.o NeuralNet.o Sparsely2dNeuralNetwork.o Connection.o Layer2d.o Neuron2dIterator.o ${SAMPLES}
LIBS =
TARGET = neural_net_2d
$(TARGET): $(OBJS)
$(CXX) -o bin/$(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
debug: $(OBJS)
$(CXX) -o bin/$(TARGET) $(OBJS) $(LIBS) $(CXXFLAGS_DEBUG)
clean:
rm -f $(OBJS) $(TARGET)
Layer.h
#ifndef LAYER_H
#define LAYER_H
#include "Neuron.h"
#include "Iterator.h"
class Layer
{
protected:
// biasNeuron
Neuron biasNeuron = 1.0;
public:
inline Layer() : biasNeuron(1.0) {}
virtual Iterator& start();
virtual Neuron& front(void);
virtual Neuron& back(void);
virtual int size();
protected:
private:
};
#endif // LAYER_H
Layer2d.h
#ifndef LAYER2D_H
#define LAYER2D_H
#include "Layer.h"
class Layer2d : public Layer
{
public: std::vector<std::vector<Neuron> > _neurons;
public:
Layer2d();
virtual ~Layer2d();
Iterator& start();
Neuron& front(void);
Neuron& back(void);
int size();
protected:
private:
};
#endif // 2DLAYER_H
Layer2d.cpp
#include "Layer2d.h"
#include "Neuron2dIterator.h"
class Neuron2dIterator;
Iterator& Layer2d::start(void)
{
Neuron2dIterator& it = (*new Neuron2dIterator(*this));
return it;
}
Neuron& Layer2d::front(void)
{
Neuron& frontNeuron = this->_neurons.front().front();
return frontNeuron;
}
Neuron& Layer2d::back(void)
{
Neuron& backNeuron = this->_neurons.back().back();
return backNeuron;
}
int Layer2d::size(void)
{
int size = this->_neurons.back().size() * this->_neurons.size();
return size;
}
Layer2d::Layer2d()
{
//ctor
}
Layer2d::~Layer2d()
{
//dtor
}
LineLayer.h
#ifndef LINELAYER_H
#define LINELAYER_H
#include "Layer.h"
#include "Neuron.h"
#include <vector>
using namespace std;
class LineIterator;
class LineLayer : public Layer
{
public: std::vector<Neuron> _neurons;
public:
LineLayer();
protected:
private:
};
#endif // LINELAYER_H
LineLayer.cpp
#include "LineLayer.h"
#include "LineIterator.h"
Iterator& LineLayer::start()
{
LineIterator& it = (*new LineIterator());
return it;
}
Neuron& LineLayer::front()
{
Neuron& frontNeuron = this->_neurons.front();
return frontNeuron;
}
Neuron& LineLayer::back()
{
Neuron& backNeuron = this->_neurons.back();
return backNeuron;
}
int LineLayer::size()
{
return this->_neurons.size();
}
LineLayer::LineLayer()
{
//ctor
}
LineLayer::~LineLayer()
{
//dtor
}
Thnx for help!
As explained at https://gcc.gnu.org/wiki/VerboseDiagnostics#missing_vtable the vtable will be in the same object file as the first non-inline virtual function, which is Layer::start. You haven't defined that function, so the compiler never generated the vtable.
To fix the linker error be sure you have provided a definition for the first non-inline virtual function declared in the class.
This week I started to upgrade my knowledge from C to C++, I would like to overload some operators
I have a class called Matrix
#include "lcomatrix.h"
inline Matrix::Matrix(unsigned rows, unsigned cols) :
rows_(rows), cols_(cols)
{
data_ = new double[rows * cols];
}
inline Matrix::~Matrix() {
delete[] data_;
}
inline double& Matrix::operator()(unsigned row, unsigned col) {
return data_[cols_ * row + col];
}
inline double Matrix::operator()(unsigned row, unsigned col) const {
return data_[cols_ * row + col];
}
The content of lcomatrix.h is
#include <iostream>
class Matrix {
public:
Matrix(unsigned rows, unsigned cols);
double& operator()(unsigned row, unsigned col);
double operator()(unsigned row, unsigned col) const;
~Matrix(); // Destructor
Matrix& operator=(Matrix const& m); // Assignment operator
private:
unsigned rows_, cols_;
double* data_;
};
Main.cpp
#include "lcomatrix.h"
#include <iostream>
/*-
* Application entry point.
*/
int main(void) {
Matrix mx(12,12);
//std::cout << mx << std::endl;
return 0;
}
Make file:
CPPFLAGS=-I /path/lcomatrix/
EFLAGS=
all : main.o lcomatrix.o
g++ $(EFLAGS) -o main.out main.o lcomatrix.o
main.o: lcomatrix.o
g++ $(EFLAGS) $(CPPFLAGS) -c main.cpp
lcomatrix.o:
g++ $(EFLAGS) -c /home/robu/UbuntuOne/ChibiOS-RPi/lcomatrix/lcomatrix.cpp
clean:
rm *.o main.out
When I try to build I receive the following link error:
make all
g++ -c /home/robu/UbuntuOne/ChibiOS-RPi/lcomatrix/lcomatrix.cpp
g++ -I /home/robu/UbuntuOne/ChibiOS-RPi/lcomatrix/ -c main.cpp
g++ -o main.out main.o lcomatrix.o
main.o: In function `main':
main.cpp:(.text+0x1b): undefined reference to `Matrix::Matrix(unsigned int, unsigned int)'
main.cpp:(.text+0x2c): undefined reference to `Matrix::~Matrix()'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
I guess this a really stupid error, but as a beginner I couldn't figure out the solution.
Your method definitions are all inline. In order to inline a function, the compiler needs to see its definition whenever it is compiling the code that uses it.
Either put the function definitions somewhere they can be seen at the point of use - in the header, or in another file #included by Main.cpp - or don't mark them as inline.
The following are the files involved and a short description:
arrayListType.h, arrayListTypeImp.cpp: declare and implement arrayListType class and its functions.
unorderedarrayListType.h unorderedArrayListTypeImp.cpp: inherit arrayListType class and declare unorderedarrayListType class and implement virtual functions of arrayListType class.
Ch13_Ex6.cpp: Instantiates an object of class unorderedArrayListType and runs some tests.
I am having a compilation error, which I think is due to the Makefile. The following is the error:
unorderedArrayListTypeImp.cpp:4: error: expected unqualified-id before 'using'
unorderedArrayListTypeImp.cpp: In member function 'virtual void unorderedArrayListType::insertAt(int, int)':
unorderedArrayListTypeImp.cpp:11: error: 'cout' was not declared in this scope
unorderedArrayListTypeImp.cpp:11: error: 'endl' was not declared in this scope
unorderedArrayListTypeImp.cpp:13: error: 'cout' was not declared in this scope
Line 4 has a using namespace std; command. The line before that is #include "arrayListType.h". I have tried the following variations in the Makefile but neither worked:
Version 1
all: Ch13_Ex6
arrayListTypeImp.o: arrayListType.h arrayListTypeImp.cpp
g++ -c -Wall arrayListType.h arrayListTypeImp.cpp
unorderedArrayListTypeImp.o: arrayListTypeImp.o unorderedArrayListType.h unorderedArrayListTypeImp.cpp
g++ -c -Wall arrayListTypeImp.o unorderedArrayListType.h unorderedArrayListTypeImp.cpp
Ch13_Ex6.o: Ch13_Ex6.cpp
g++ -c -Wall Ch13_Ex6.cpp
Ch13_Ex6: arrayListTypeImp.o unorderedArrayListTypeImp.o Ch13_Ex6.o
g++ -Wall Ch13_Ex6.o arrayListTypeImp.o unorderedArrayListTypeImp.o -o Ch13_Ex6
Version 2:
all: Ch13_Ex6
arrayListTypeImp.o: arrayListType.h arrayListTypeImp.cpp
g++ -c -Wall arrayListType.h arrayListTypeImp.cpp
unorderedArrayListTypeImp.o: unorderedArrayListType.h unorderedArrayListTypeImp.cpp
g++ -c -Wall unorderedArrayListType.h unorderedArrayListTypeImp.cpp
Ch13_Ex6.o: Ch13_Ex6.cpp
g++ -c -Wall Ch13_Ex6.cpp
Ch13_Ex6: arrayListTypeImp.o unorderedArrayListTypeImp.o Ch13_Ex6.o
g++ -Wall Ch13_Ex6.o arrayListTypeImp.o unorderedArrayListTypeImp.o -o Ch13_Ex6
Both versions compile arrayListTypeImp.o and give the error shown above when compiling unorderedArrayListTypeImp.o. The following is the complete compile output:
make
g++ -c -Wall unorderedArrayListType.h unorderedArrayListTypeImp.cpp
arrayListTypeImp.o
unorderedArrayListType.h:16: error: expected unqualified-id at end of input
unorderedArrayListTypeImp.cpp:4: error: expected unqualified-id before 'using'
unorderedArrayListTypeImp.cpp: In member function 'virtual void unorderedArrayListType::insertAt(int, int)':
unorderedArrayListTypeImp.cpp:11: error: 'cout' was not declared in this scope
unorderedArrayListTypeImp.cpp:11: error: 'endl' was not declared in this scope
unorderedArrayListTypeImp.cpp:13: error: 'cout' was not declared in this scope
unorderedArrayListTypeImp.cpp:13: error: 'endl' was not declared in this scope
Code for arrayListType.h:
#ifndef H_arrayListType
#define H_arrayListType
class arrayListType
{
public:
bool isEmpty() const;
bool isFull() const;
int listSize() const;
int maxListSize() const;
void print() const;
bool isItemAtEqual(int location, int item) const;
virtual void insertAt(int location, int insertItem) = 0;
virtual void insertEnd(int insertItem) = 0;
void removeAt(int location);
int retrieveAt(int location) const;
virtual void replaceAt(int location, int repItem) = 0;
void clearList();
virtual int seqSearch(int searchItem) const = 0;
virtual void remove(int removeItem) = 0;
arrayListType(int size = 100);
arrayListType(const arrayListType& otherList);
virtual ~arrayListType();
protected:
int *list;
int length;
int maxSize;
};
#endif
Code for unorderArrayListTypeImp.cpp:
#include <iostream>
#include "unorderedArrayListType.h"
using namespace std;
void unorderedArrayListType::insertAt(int location,
int insertItem)
{
if (location < 0 || location >= maxSize)
cout << "The position of the item to be inserted "
<< "is out of range." << endl;
else if (length >= maxSize) //list is full
cout << "Cannot insert in a full list" << endl;
else
{
for (int i = length; i > location; i--)
list[i] = list[i - 1]; //move the elements down
list[location] = insertItem; //insert the item at
//the specified position
length++; //increment the length
}
} //end insertAt
void unorderedArrayListType::insertEnd(int insertItem)
{
if (length >= maxSize) //the list is full
cout << "Cannot insert in a full list." << endl;
else
{
list[length] = insertItem; //insert the item at the end
length++; //increment the length
}
} //end insertEnd
// More virtual functions implemented and finally a constructor
unorderedArrayListType::unorderedArrayListType(int size)
: arrayListType(size)
{
} //end constructor
You did not #include <iostream> in arrayListType.h, but did it in arrayListType.cpp, before you #include "arrayListType.h" there. You need to place #include <iostream> into arrayListType.h before you use std::cout or std::endl.
To avoid such mistakes it is good to place the interface header as the first #include statement int the implementation file.
I am guessing that the error is in unorderedArrayListType.h, you likely have a missing semicolon or something. Looking in the Makefile will do nothing to solve that error.
EDIT: Woah, there actually is something wrong with your Makefile! Heh, I just looked at it and you have the following:
g++ -c -Wall arrayListType.h arrayListTypeImp.cpp
Don't pass .h files to g++!, only the .cpp files. So write it like this:
g++ -c -Wall arrayListTypeImp.cpp
Likewise:
g++ -c -Wall unorderedArrayListType.h unorderedArrayListTypeImp.cpp
should be:
g++ -c -Wall unorderedArrayListTypeImp.cpp
Evan Teran is probably right. expected unqualified-id before '...' usually means you missed a semicolon before that line. If it turns out it really is your makefile, here's some general makefile advice:
Use variables. Instead of
g++ -c -Wall ...
you can do
CXX_OPTS= -Wall -O3
...
g++ -c $(CXX_OPTS) ...
Use pattern rules. Rather than
arrayListTypeImp.o: arrayListType.h arrayListTypeImp.cpp
g++ -c -Wall arrayListType.h arrayListTypeImp.cpp
unorderedArrayListTypeImp.o: unorderedArrayListType.h unorderedArrayListTypeImp.cpp
g++ -c -Wall unorderedArrayListType.h unorderedArrayListTypeImp.cpp
Ch13_Ex6.o: Ch13_Ex6.cpp
g++ -c -Wall Ch13_Ex6.cpp
you can use
%.o:%.cpp
g++ $(CXX_OPTS) -c $< -o $#
This should shorten your makefile and make it easier to debug and find your problem. If you want more information, check this out.
I have a class 'Vector3' which is compiled successfully. It contains both non-friend and friend functions, for example, to overload * and << operators when Vector3 is the second operand. The problem is I can't link to any of the friend functions, be it operator overloaded or not. So I can confirm that the error is not specific to operator overloading. The g++ command used for linking is as follows (please also see Makefile at the end),
g++ -Wall -W -I./ -g -o main.out main.o Vector3.o
which gave the following errors,
main.cpp:7: undefined reference to `operator*(double, Vector3 const&)'
main.cpp:9: undefined reference to `mag(Vector3 const&)'
main.cpp:10: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Vector3 const&)'
Below is the relevant code in my source files. I follow the practice of making separate .hpp and .cpp for every class.
/* file Vector3.hpp */
struct Vector3 {
...
Vector3 operator*(const double k) const;
friend Vector3 operator*(const double k, const Vector3 &vec);
double magnitude() const;
friend double mag(const Vector3 &vec);
friend std::ostream& operator<<(std::ostream& output, const Vector3 &vec);
...
}
/* file Vector3.cpp */
Vector3 operator*(const double k, const Vector3 &vec) {
...
}
inline double mag(const Vector3 &vec) {
...
}
std::ostream& operator<<(std::ostream& output, const Vector3 &vec) {
...
}
/* file main.cpp */
#include "Vector3.hpp"
int main() {
Vector3 M(1, 1, 1);
M = M * 2.0; // own operator* links successfully
M = 10.0 * M; // friend operator* doesn't link
double m = M.magnitude(); // own function magnitude() links successfully
double n = mag(M); // friend function mag() doesn't link
std::cout << M; // friend operator<< doesn't link
}
Finally, this is my Makefile.
CXX = g++
CXXFLAGS = -Wall -W $(INCPATH) -g
INCPATH = -I./
OBJS = main.o Vector3.o
main.out: $(OBJS)
$(CXX) $(CXXFLAGS) -o $# $(OBJS) $(LIBPATH)
main.o: main.cpp
Vector3.o: Vector3.cpp
clean:
rm -f $(OBJS) main.out
The strangest thing is that if I include the Vector3.cpp file as well in main.cpp and then remove Vector3.o from OBJS in Makefile, the program links successfully. I cannot make sense of this. Please help me!!
The definition of friend operator* uses fp_type while the friend declaration uses double as the first parameter. This will only work as intended if fp_type is a typedef-name for double. Are you sure fp_type actually stands for double? I can't see it from the code you posted.
The problem with mag is rather obvious: you defined it as inline in .cpp file. Inline function definitions have to be visible everywhere they are used, meaning that normally they should be placed in the header file.