C++ : Error Redefinition & Previously Declared - c++

I am half way into my course.I am unable to understand the logic behind the errors I am receiving. I have already tried to counter it by using appropriate directives at the bottom of my Array.h file. I am receive the following 2 errors across all functions:
note: 'const T& udbhavAg::Container::Array::operator const' previously declared here
const T &Array::operator[](int index) const {
error: redefinition of 'const T& udbhavAg::Container::Array::operator const'
const T &Array::operator[](int index) const {
My questions are the following :
Why are the files being declared twice?
Why are they being redefined?
Main.cpp
#include <iostream>
#include "Point.h"
#include "Line.h"
#include "Circle.h"
#include "Array.h"
#include "ArrayException.h"
using namespace std;
using namespace udbhavAg::CAD;
using namespace udbhavAg::Container;
using namespace udbhavAg;
int main()
{
Array<Point> points(10);
return 0;
}
Array.h
#include "Point.h"
#include <cstring>
#include "ArrayException.h"
#ifndef ARRAY_H
#define ARRAY_H
//#include "Array.cpp"
namespace udbhavAg
{
namespace Container
{
template <typename T>
class Array {
private:
T *m_data;
int m_size;
public:
Array();
Array(int size);
Array(const Array &obj);
virtual ~Array();
//const Array operator= ( const Array & source);
Array<T> &operator=(const Array &source);
int Size() const;
void setElement(int index, T p);
T &getElement(int index) const;
T &operator[](int index);
const T &operator[](int index) const;
};
}
}
#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif
#endif ARRAY_H
Array.cpp
#include "Array.h"
#include "ArrayException.h"
namespace udbhavAg
{
namespace Container
{
template<typename T>
Array<T>::Array():m_size(3),m_data(new T[m_size]) {}
template<typename T>
Array<T>::Array(int size): m_size(size), m_data(new T[m_size]) {}
template<typename T>
Array<T>::~Array()
{
delete[] m_data;
cout << "Destructor called" << endl;
}
template<typename T>
Array<T>::Array(const Array &obj) {
m_size = obj.m_size;
m_data = new CAD::Point[m_size];
for (int i = 0; i < m_size; i++)
{
m_data[i] = obj.operator[](i);
}
}
template<typename T>
int Array<T>::Size() const
{
return m_size;
}
template<typename T>
T &Array<T>::getElement(int index) const
{
try
{
if (index >= m_size || index < 0)
{
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
void Array<T>::setElement(int index, T p)
{
try
{
if (index >= m_size || index < 0)
{
// OutofBoundsException error = OutofBoundsException(index);
// ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
m_data[index] = p;
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
Array<T> & Array<T>::operator=(const Array &source)
{
if(&source != this){ //edited self assignment test
if(m_size != source.m_size){//diff sized arrays
delete [] m_data; //reclaim space
m_size = source.m_size;
m_data = new CAD::Point[m_size]; //space created
}
}
for(int i=0; i<m_size; i++){
m_data[ i ] = source.m_data[i];}
return *this; //enables cascading a=b=c
}
template<typename T>
T &Array<T>::operator[](int index) {
try
{
if (index >= m_size || index < 0)
{
// OutofBoundsException error = OutofBoundsException(index);
// ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
template<typename T>
const T &Array<T>::operator[](int index) const {
try
{
if (index >= m_size || index < 0)
{
// OutofBoundsException error = OutofBoundsException(index);
// ArrayException& abc = error;
throw (OutofBoundsException(index));
}
else
{
return m_data[index];
}
}
catch (ArrayException &error)
{
cout << error.GetMessage();
}
}
}
}

probably because in Array.h :
#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif
so Array.cpp #include Array.h whose #include Array.cpp because Array_cpp is not defined
Do not include source file in your header files
Out of that why in Array.h
#ifndef ARRAY_H
#define ARRAY_H
is not at the beginning of the file ?
So possible exclusive solutions to solve are :
to remove #include "Array.h" at the beginning of Array.cpp
to add #define Array_cpp to be the very first line in Array.cpp
in both case you must not compile Array.cpp in your Makefile or equivalent nor link with it.
But the best one is to replace in Array.h
#ifndef Array_cpp // Must be the same name as in source file #define
#include "Array.cpp"
#endif
by the definitions from the file Array.cpp and to delete the file Array.cpp.
The template classes are special, all template methods must be defined in the header file and only in it, not in a source file also compiled as a 'normal' source file, the compiler does the stuff for you

Related

C++ Template: Expected primary-expression before 'double' error

When I try to run an instance of the matrix class I'm writing, I get the following error.
main.cpp|6|error: expected primary-expression before 'double'|
I believe there's something wrong with the constructor but i can't figure what.
How can I fix my code? Below what I've written so far.
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
template<class T>
class matrix{
public:
matrix(int n, int m);
~matrix();
void fillM(T n);
void print() const;
private:
T** body_;
int lin_;
int col_;
void eraseMatrix();
};
#endif
matrix.cpp
#include "matrix.h"
#include <iostream>
template<class T>
matrix<T>::matrix(int n, int m):col_(m),lin_(n),body_(new T*[n]){
for(int i=0;i<n;i++){
body_[i] = new T[m];
}
}
template<class T>
matrix<T>::~matrix<T>(){
eraseMatrix();
}
template<class T>
void matrix<T>::eraseMatrix(){
for(int i=0;i<lin_;i++){
delete [] body_[i];
}
delete [] body_;
return;
}
template<class T>
void matrix<T>::fillM(T n){
int j;
for(int i = 0;i<lin_;i++){
for(j = 0;j<col_;j++){
body_[i][j] = n;
}
}
return;
}
template<class T>
void matrix<T>::print() const{
int j;
for(int i=0;i<lin_;i++){
for(j=0;j<col_;j++){
std::cout<<body_[i][j]<<" ";
}
std::cout<<std::endl;
}
}
main.cpp
#include <iostream>
#include "matrix.h"
using namespace std;
int main(){
matrix<double>::matrix<double> A(5,5);//error happens here
A.fillM(5.2);
A.print();
return 0;
}
}
You don't need to write matrix<double>::matrix<double> to construct an instance. Just matrix<double> A(5,5);.

Question with constructor in C++ ArrayStack

I am in the process of constructing a StackArray. I already have a "Stack.h" implemented with a constructor. I was wondering what I would do in my "StackArray.h" file to use the Stack.h file. I was thinking to use inheritance but it was giving me a error.
My code is as follows:
Array.h
#include <iostream>
#include <assert.h>
using namespace std;
#ifndef _ARRAY_H
#define _ARRAY_H
template<class T>
class Array{
private:
T *a;
int length;
public:
// constructor
Array (int len){
length = len;
a = new T[length];
for (int i = 0; i < len; i++){
a[i]=0;
}
}
// destructor
~Array()
{delete[] a;}
// operator overload
T& operator [](int i){
assert (i>=0 && i < length);
return a[i];
}
//get the length of the array
int arraylength(){
return length;
}
};
#endif
ArrayStack.h
#ifndef _ARRAYSTACK_H_
#define _ARRAYSTACK_H_
#include "Array.h"
using namespace std;
template<class T>
class ArrayStack
{
protected:
Array<T> a;
int n;
public:
ArrayStack(int len);
virtual ~ArrayStack();
};
template<class T>
ArrayStack<T>::ArrayStack(int len){
// I don't know what to do here to implemented constructor from another class.
}
#endif
Any suggestion would be great, Thank you
Andy

unable to seperate header classes. I get "does not name a type"

I made a class with a header and a cpp and a main class. When doing so all is good! When separating a class that I will have 2 classes (header+cpp) and one main Class A (Board) does not recognize class B (IllegalCoordinateException) even though I inserted the include. This is probably a newbies question and I might lose some points, but I am stuck in finding my problem.
Here is my working code(stripped down to only the important parts):
main.cpp
#include "Board.h"
#include <iostream>
using namespace std;
int main() {
Board board1{4}; // Initializes a 4x4 board
try {
board1[{3,4}]='O'; // This should raise an exception
} catch (const IllegalCoordinateException& ex) {
cout << "Illegal coordinate" << ex.theCoordinate() << endl; // prints "Illegal coordinate: 3,4"
}
return 0;
}
Board.h
#ifndef CIRC_H
#define CIRC_H
#include <iostream>
#include <string>
using namespace std;
struct coord {
int x;
int y;
};
class IllegalCoordinateException{
coord _coord;
public:
IllegalCoordinateException(coord c){
_coord = c;
}
string theCoordinate() const{
return to_string(_coord.x)+","+to_string(_coord.y);
}
};
class xo{
char x;
public:
char getChar() const{return x;}
char& operator= (const char c){x = c;}
xo& operator= (const xo _xo){
x = _xo.getChar();
return *this;
}
void clear(){
x = '.';
}
operator char() const{
return x;
}
};
class Board{
private:
coord _coord;
xo** board;
int size;
public:
Board();
Board(int v);
~Board();
xo& operator[](coord c); // here is where I use "IllegalCoordinateException"
};
#endif
Board.cpp
#include <iostream>
#include <vector>
#include "Board.h"
using namespace std;
void freeBoard(xo** board,int size){
for(int i = 0 ; i < size ; i++){
delete[] board[i];
}
}
Board::Board()
{
size = 0;
board = new xo* [size];
}
Board::Board(int v)
{
size = v;
board = new xo* [size];
for (int i=0; i<size; i++)
{
board[i] = new xo[size];
for(int j = 0 ; j < size ; j++){
board[i][j].clear();
}
}
}
Board::~Board(){
freeBoard(board,size);
delete[] board;
}
xo& Board::operator[](coord c)
{
if(c.x < size && c.y < size)
{
return board[c.x][c.y];
}
else
{
throw IllegalCoordinateException(c);
}
}
After seperation:
main.cpp
No diff
Board.h also cpp no diff
#ifndef CIRC_H
#define CIRC_H
#include "IllegalCoordinateException.h"
#include <iostream>
#include <string>
using namespace std;
struct coord {
int x;
int y;
};
class xo{
char x;
public:
char getChar() const{return x;}
char& operator= (const char c){x = c;}
xo& operator= (const xo _xo){
x = _xo.getChar();
return *this;
}
void clear(){
x = '.';
}
operator char() const{
return x;
}
};
class Board{
private:
coord _coord;
xo** board;
int size;
public:
Board();
Board(int v);
~Board();
xo& operator[](coord c);
};
#endif
IllegalCoordinateException.h // I also seperated in my code to .h and .cpp (but ofcourse there is no real diff.
#ifndef CIRC_H
#define CIRC_H
#include <iostream>
#include "Board.h"
using namespace std;
class IllegalCoordinateException{
coord _coord;
public:
IllegalCoordinateException(coord c){ _coord = c;}
string theCoordinate() const{return to_string(_coord.x)+","+to_string(_coord.y);}
};
#endif
When doing
$ g++ -g -Og -std=c++0x main.cpp Board.cpp IllegalCoordinateException.cpp
I get:
Board.cpp: In member function ‘xo& Board::operator’:
Board.cpp:60:43: error: ‘IllegalCoordinateException’ was not declared
in this scope
throw IllegalCoordinateException(c);
How can this be? I mean I am including it in the Board.h so Board.cpp is supposed to recognize it!? I tried also to include it in Board.cpp and also make a forward declaration in Board.cpp but both were frugal.
Both of your header files have #ifndef CIRC_H / #define CIRC_H.
So when the first one is included (no matter which order), it defines CIRC_H, and when the second one is included, it gets ignored because the whole file is within #ifndef CIRC_H.
Solution: use a different macro name for each header file.

Variadic parameters get does not work

I am creating CPP application that can create List's: string arrays. When initialization is called it get's variadic parameters and should insert them into a string array. It gives Segmentation error. Also if I remove Students_Second_Group.push(), everything works fine. Any suggestions?
// Main.cpp
#include "List.h"
int main() {
List Students_First_Group(4), Students_Second_Group(3);
Students_First_Group.push("Jonas Jonaits", "Tomas Tomaitis", "Petras Petraitis", "Donatas Petkevicius");
Students_Second_Group.push("Mantas Jonaitis", "Tautvydas Tomaitis", "Linas Linaitis");
return 0;
}
// List.h
#ifndef _LIST_H_
#define _LIST_H_
#include <iostream>
#include <string>
#include <vector>
#include <cstdarg>
using namespace std;
class List {
private:
size_t size;
vector<string> arr;
public:
List(int size);
void push(const char* str...);
~List();
};
#endif
// List.cpp
#include "List.h"
List::List(int s) {
if(size > 0)
size = s;
else
size = 10;
arr = vector<string> (s);
}
void List::push(const char* str...) {
va_list arg;
va_start(arg, str);
while (str) {
arr.push_back(str);
str = va_arg(arg, const char *);
}
va_end(arg);
}
List::~List() {}
you can solve your issue with varadic template but
because they are template varadic template should be put in the header
for more info http://en.cppreference.com/w/cpp/language/parameter_pack
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class List {
private:
size_t size;
vector<string> arr;
void push() {}
public:
List(int size);
template<typename ... Rest>
void push(const char* first, Rest ... rest) {
arr.push_back(first);
push(rest...);
}
~List();
};
List::List(int s) {
if(size > 0)
size = s;
else
size = 10;
arr = vector<string> (s);
}
List::~List() {}
int main() {
List Students_First_Group(4), Students_Second_Group(3);
Students_First_Group.push("Jonas Jonaits", "Tomas Tomaitis", "Petras Petraitis", "Donatas Petkevicius");
Students_Second_Group.push("Mantas Jonaitis", "Tautvydas Tomaitis", "Linas Linaitis");
return 0;
}

cannot convert 'ArithProgression*' to 'Progression*' in assignment

I had defined a class "Progression" and saved it as "Progression.h" and then i made another class "ArithProgression" which extends Progression class and saved it as "ArithProgression.h".
File: Progression.h
#ifndef PROGRESSION_H
#define PROGRESSION_H
#include <iostream>
using namespace std;
class Progression
{
public:
Progression()
{
cur=first=0;
}
Progression(long f)
{
cur=first = f;
}
void printProgression(int n)
{
cout<<firstValue();
for(int i=0;i<=n; i++)
{
cout<<' '<<nextValue();
}
}
virtual ~Progression() {}
protected:
long first;
long cur;
virtual long firstValue()
{
cur= first;
return cur;
}
virtual long nextValue()
{
return cur++;
}
};
#endif // PROGRESSION_H
FILE: ArithProgression.h
#ifndef ARITHPROGRESSION _H
#define ARITHPROGRESSION _H
#include "Progression.h"
class ArithProgression :public Progression
{
public:
ArithProgression(long i=1)
:Progression()
{
inc=i;
}
virtual ~ArithProgression () {}
protected:
long inc;
virtual long nextValue()
{
cur+=inc;
return cur;
}
private:
};
#endif // ARITHPROGRESSION _H
FILE: main.cpp
#include <iostream>
#include "Progression.h"
#include "ArithProgression.h"
using namespace std;
int main()
{
Progression* p;
p= new ArithProgression();
p->printProgression(10);
delete p;
}
I am getting an error: "cannot convert 'ArithProgression*' to 'Progression*' in assignment" in code blocks 12.11
Please Help
Your code, as you posted it, works just fine. Since ArithProgression is indeed a subclass of Progression, the above code cannot trigger that error.