Template Classes and methods in C++ - c++

I have been using C# for about a year now, I am attempting to move on to C++ in visual studio. Anyway I am trying to make a generic binary tree in C++ and have run into a few compile errors which I cannot seem to fix.
Initial research seemed to point towards putting the class template inside the header file, yet this gave me a host of other errors.
Some advice from someone with a bit more experience would be very much appreciated.
Thanks
Here is the code so far.
#include "stdafx.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
TreeNode<int> IntTree(1, TreeNode<int>(1), TreeNode<int>(2));
cout << IntTree.toString() << endl;
return 0;
}
template<class TData> class TreeNode
{
private:
TData Data;
TreeNode<TData>& Left;
TreeNode<TData>& Right;
void setData(TData data)
{
Data = data;
}
public:
TreeNode<TData>(TData data)
{
setData(data);
}
TreeNode<TData>(TData data, TreeNode<TData> leftNode, TreeNode<TData> rightNode)
{
setData(data);
setLeft(leftNode);
setRight(rightNode);
}
void setLeft(TreeNode<TData>& leftNode)
{
Left = leftNode;
}
void setRight(TreeNode<TData>& rightNode)
{
Right = rightNode;
}
TreeNode<TData>& getLeft()
{
return Left;
}
TreeNode<TData>& getRight()
{
return Right;
}
TData& getData()
{
return &Data;
}
string toString()
{
return Left->toString() + Data + Right->toString();
}
};
error C2228: left of '.toString' must have class/struct/union.
error C2065: 'TreeNode' : undeclared identifier.
error C2065: 'IntTree' : undeclared identifier
error C2062: type 'int' unexpected.

At the point of usage in your _tmain() TreeNode<> isn't yet declared.
You must put the complete template class declaration/definition before _tmain(), or even better put it in a separate header file, and include that.

Related

C++ Builder Pattern with Forward Declaration [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I recently got stuck in a situation. In the first version, everything is implemented in header file and it works fine. In the second version when i tried to separate implementation from header declarations, I got many errors. In the below lines, i m going to demonstrate problem. Thanks in advance..
First Version (it works fine!)
cameravalue.h
#ifndef CAMERAVALUE_H
#define CAMERAVALUE_H
#include <string>
class CameraValue
{
private:
class CameraProperties
{
private:
CameraProperties()
: mId(-1),
mName(),
mAddress(),
mExposure(),
mFocus()
{}
int mId;
std::string mName;
std::string mAddress;
std::string mExposure;
long long mFocus;
friend class CameraValue;
friend class CameraBuilder;
};
public:
class CameraBuilder
{
public:
CameraBuilder(int id)
{
mProperties.mId = id;
}
CameraBuilder& setName(std::string& name)
{
mProperties.mName = name;
return *this;
}
CameraBuilder& setAddress(std::string& adress)
{
mProperties.mAddress = adress;
return *this;
}
CameraBuilder& setExposure(std::string& exposure)
{
mProperties.mExposure = exposure;
return *this;
}
CameraBuilder& setFocus(int focus)
{
mProperties.mFocus = focus;
return *this;
}
CameraValue build()
{
return CameraValue(mProperties);
}
private:
CameraProperties mProperties;
};
private:
CameraValue(const CameraProperties& properties)
:mProperties(properties)
{}
CameraProperties mProperties;
};
#endif // CAMERAVALUE_H
main.cpp
#include "cameravalue.h"
#include <iostream>
int main(int argc, char *argv[])
{
CameraValue cm = CameraValue::CameraBuilder(1).setName(std::string("Huseyin")).build();
return 0;
}
Second Version (Don't work)
cameravalue.h
#ifndef CAMERAVALUE_H
#define CAMERAVALUE_H
#include <string>
class CameraValue
{
private:
class CameraProperties;
public:
class CameraBuilder;
private:
CameraValue(const CameraProperties& properties);
CameraProperties mProperties;
};
#endif // CAMERAVALUE_H
cameravalue.cpp
#include "cameravalue.h"
#include <string>
class CameraValue::CameraProperties
{
private:
CameraProperties()
: mId(-1),
mName(),
mAddress(),
mExposure(),
mFocus()
{}
int mId;
std::string mName;
std::string mAddress;
std::string mExposure;
long long mFocus;
friend class CameraValue;
friend class CameraBuilder;
};
class CameraValue::CameraBuilder
{
public:
CameraBuilder(int id)
{
mProperties.mId = id;
}
CameraBuilder& setName(std::string& name)
{
mProperties.mName = name;
return *this;
}
CameraBuilder& setAddress(std::string& adress)
{
mProperties.mAddress = adress;
return *this;
}
CameraBuilder& setExposure(std::string& exposure)
{
mProperties.mExposure = exposure;
return *this;
}
CameraBuilder& setFocus(int focus)
{
mProperties.mFocus = focus;
return *this;
}
CameraValue build()
{
return CameraValue(mProperties);
}
private:
CameraProperties mProperties;
};
CameraValue::CameraValue(const CameraProperties& properties)
: mProperties(properties)
{}
main.cpp
#include "cameravalue.h"
#include <iostream>
int main(int argc, char *argv[])
{
CameraValue cm = CameraValue::CameraBuilder(1).setName(std::string("Huseyin")).build();
return 0;
}
Compile Errors
cameravalue.cpp
c:\users\huseyin\documents\builderpattern\cameravalue.h(20) : error
C2079: 'CameraValue::mProperties' uses undefined class
'CameraValue::CameraProperties' ..\BuilderPattern\cameravalue.cpp(74)
: error C2440: 'initializing' : cannot convert from 'const
CameraValue::CameraProperties' to 'int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
..\BuilderPattern\cameravalue.cpp(74) : error C2439:
'CameraValue::mProperties' : member could not be initialized
c:\users\huseyin\documents\builderpattern\cameravalue.h(20) : see declaration of 'CameraValue::mProperties'
c:\users\huseyin\documents\builderpattern\cameravalue.h(20) : error
C2079: 'CameraValue::mProperties' uses undefined class
'CameraValue::CameraProperties' ..\BuilderPattern\main.cpp(9) : error
C2440: '<function-style-cast>' : cannot convert from 'int' to
'CameraValue::CameraBuilder'
Source or target has incomplete type ..\BuilderPattern\main.cpp(9) : error C2228: left of '.setName' must
have class/struct/union ..\BuilderPattern\main.cpp(9) : error C2228:
left of '.build' must have class/struct/union
..\BuilderPattern\main.cpp(9) : error C2512: 'CameraValue' : no
appropriate default constructor available
..\BuilderPattern\main.cpp(10) : error C2039: 'getName' : is not a
member of 'CameraValue'
c:\users\huseyin\documents\builderpattern\cameravalue.h(8) : see declaration of 'CameraValue'
Definition of class CameraBuilder should be visible in main.cpp, so you can't just forward-declare it in cameravalue.h. But you can make the definitions of its member functions out-of-line:
// cameravalue.h
class CameraValue {
class CameraBuilder {
public:
CameraBuilder(int id);
...
};
};
// cameravalue.cpp
CameraValue::CameraBuilder::CameraBuilder(int id) {
...
}

Making Priority Queue of Objects

I have error in line 7 that missing ; before * I want to make Priority Queue of Objects which gets priority by Student ID and also it is not necessary to have object pointer it can be object itself
#include<iostream>
#include<string>
using namespace std;
struct node
{
int priority;
Student * S;
node * next;
};
class Student
{
int ID;
string name;
public:
Student()
{
cin>>ID;
cin>>name;
}
void out()
{
cout<<"ID is : "<<ID<<" "<<"Name is : "<<name<<endl;
}
};
class Priority_Queue
{
node * head;
//node * back;
public:
Priority_Queue()
{
head=NULL;
//back=NULL;
}
void push(Student * Q, int a)
{
node * p=new node;
p->next=NULL;
p->priority=a;
p->S=Q;
if(head==NULL)
head=p;
else
{
node * q=head;
node * r=NULL;
while(a<=q->priority)
{
r=q;
q=q->next;
}
r->next=p;
p->next=q;
}
}
Student * pop()
{
if(isempty())
{
cout<<"Empty"<<endl;
exit(1);
}
else
{
return head->S;
head =head->next;
}
}
bool isempty()
{
if(head==NULL)
return true;
else return false;
}
};
int main()
{
Student S1,S2,S3,S4;
return 0;
}
Errors in my Code
1>d:\codes\priority queue\priority queue\1.cpp(7): error C2143: syntax error : missing ';' before '*'
1>d:\codes\priority queue\priority queue\1.cpp(7): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\codes\priority queue\priority queue\1.cpp(7): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\codes\priority queue\priority queue\1.cpp(41): error C2039: 'S' : is not a member of 'node'
1> d:\codes\priority queue\priority queue\1.cpp(5) : see declaration of 'node'
1>d:\codes\priority queue\priority queue\1.cpp(66): error C2039: 'S' : is not a member of 'node'
1> d:\codes\priority queue\priority queue\1.cpp(5) : see declaration of 'node'
Actually the problem is, that the struct node does not know about the class student, as it is defined after. A workaround is to declare Student before node, but you could aswell put Student in an extra header and include that header in the node header (personally I'd prefer that way.).
class Student;
struct node
{
int priority;
Student * S;
node * next;
};
You should use forward declaration:
struct node;
class Student;
struct node
{
int priority;
Student * S;
node * next;
};
// . . .

C++ list, operator == problems

Yeah i forgot about including header file.
I added inline bool operator== as you suggested but still bunch of troubles showed up themselves. Maybe i should stop for now but i don't want :D
By the way, getTytul() returns string.
So here is what i get:
header:
#include "Pozycja.h"
#include "IZarzadzaniePozycjami.h"
#include <iostream>
#include <list>
inline bool operator==(std::string& s, Katalog& katalog)
{
return katalog == s;
}
class Katalog
: public IZarzadzaniePozycjami
{
private:
std::string dzialTematyczny;
public:
void ZnajdzPozycjePoTytule(std::string tytul);
void ZnajdzPozycjePoId(int id);
void WypiszWszystkiePozycje();
Katalog(void);
Katalog(std::string dzialTematyczny_);
void DodajPozycje(Pozycja);
std::list<Pozycja> lista;
~Katalog(void);
};
cpp:
#include "Katalog.h"
#include <iterator>
Katalog::Katalog(void)
{
dzialTematyczny= "Nieznany dzial tematyczny";
}
Katalog::Katalog(std::string dzialTematyczny_):dzialTematyczny(dzialTematyczny_){}
void Katalog::DodajPozycje(Pozycja a){
std::cout << " Dodano pozycje";
lista.push_back(a);
}
void Katalog::ZnajdzPozycjePoTytule(std::string tytul){
for(std::list<Pozycja>::iterator iter = lista.begin(); iter!= lista.end();++iter)
{
if(tytul == iter->getTytul())
{
//std::cout << " Mamy tytul: "<< iter->getTytul() << std::endl;
}
}
}
void Katalog::ZnajdzPozycjePoId(int id){
for(std::list<Pozycja>::iterator iter = lista.begin(); iter!= lista.end();++iter)
{
if(id == iter->getId())
{
std::cout << " Mamy id: "<< iter->getId() << std::endl;
}
}
}
void Katalog::WypiszWszystkiePozycje(){
for(unsigned int i=0; i<lista.size(); ++i)
{
lista.front().WypiszInfo();
}
}
Katalog::~Katalog(void)
{
}
Errors:
1>c:\users\komputer\documents\visual studio 2012\projects\project1\katalog.h(6): error C2061: syntax error : identifier 'Katalog'
1>c:\users\komputer\documents\visual studio 2012\projects\project1\katalog.h(7): error C2805: binary 'operator ==' has too few parameters
1>c:\users\komputer\documents\visual studio 2012\projects\project1\katalog.h(8): error C2065: 'katalog' : undeclared identifier
Two immediate problems: You have not declared the IZarzadzaniePozycjami class anywhere. And having the equality operator in the class forces you to have an instance of the class on the left side of the comparison, and the argument on the right side.
The first you can solved by including the file where IZarzadzaniePozycjami is defined.
The second you can solved by adding a standalone and global helper function:
inline bool operator==(const std::string& s, const Katalog& katalog)
{
return katalog == s; // "Reverse" the arguments
}
Note: I made the function above inline so you can add it to the header file.
The first error message says that in the class definition
class Katalog
: public IZarzadzaniePozycjami
{
//...
the compiler knows nothing about definition of its base class IZarzadzaniePozycjami
Maybe you forgot to include the header with the corresponding definition.
The second error means that in the condition
if(tytul == iter->getTytul())
where tytul has type std::string the right operand that is returned by functionj iter->getTytul() has no type std::string.

How to fix error C2511: overloaded member function not found in C++?

I have a problem to pass my own class as a parameter.
Here is my codes:
PayloadContainer.h
namespace Project
{
namespace C
{
namespace Helper
{
class PayloadItem
{
public:
string Key;
string Value;
char Type;
char Mode;
char IsArray;
int FieldCount;
char FieldType;
int RowCount;
};
class PayloadContainer
{
public:
PayloadContainer( const char *Command );
PayloadContainer(void);
~PayloadContainer(void);
public:
vector<PayloadItem> PayloadItems;
};
}
}
}
ParseBinary.h
namespace Project
{
namespace C
{
namespace Helper
{
class ParseBinary
{
public:
ParseBinary(void);
~ParseBinary(void);
private:
void WriteRequestToBinary( const char *BinFileName );
void WriteRequestRecord( unsigned char file[], PayloadItem& item, string charSet );
};
}
}
}
ParseBinary.cpp
namespace Project
{
namespace C
{
namespace Helper
{
void ParseBinary::WriteRequestToBinary( const char *BinFileName )
{
unsigned char in;
// Do Something
for (auto &item : _payload->PayloadItems)
{
// Do Something
WriteRequestRecord( in, (Helper::PayloadItem)item, _payload->CharSet );
}
}
void ParseBinary::WriteRequestRecord( unsigned char file[], PayloadItem& item, string charSet )
{
-----> here, I get "error C2511: overloaded member function not found".
}
}
}
}
What I am trying to do is iterating vector where PayloadItem is my own class, and pass that class to a function.
But, when I build it I get this error C2511: overloaded member function not found error.
Please tell me where to fix this.
EDIT
This is the error message.
Error 9 error C2061: syntax error : identifier 'PayloadItem' c:\webdev\Project.c.helper\ParseBinary.h 46 1 Project.C.Helper
error C2511: overloaded member function not found in 'Project::C::Helper::ParseBinary' c:\webdev\Project.c.helper\ParseBinary.cpp 958 1 Project.C.Helper

Syntax error: Array of Vectors in OO C++

I've got an outline of a HashTable class I'm trying to make. I'm getting 3 errors output from Visual Studio, but I can't see the problem here. I'm fairly new to OO in C++ so it's probably something i've missed. It claims there is a problem with my array of vectors. The errors are:
error C2143: syntax error : missing ';' before '<' line 10
error C2238: unexpected token(s) preceding ';' line 10
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int line 10
Here's my complete class, it's pretty empty right now:
#include <iostream>
#include <vector>
#include "stdafx.h"
using namespace std;
class HashTable
{
private:
const static int buckets = 100;
vector<int> hashTable[buckets]; //Internal storage
int hash(int toHash); //Performs hash function
public:
HashTable(); //Constructor
HashTable(int s); //Constructor
~HashTable(); //Destructor
void add(int toAdd); //Adds an element to the HashTable
void remove(int toDelete); //Deletes an element from the HashTable
bool search(int toSearch); //Returns true if element in HashTable, false otherwise
int getSize(); //Returns size of HashTable
void print(); //Prints current state of the hashtable
//TODO more methods...?
};
//Definitions...
HashTable::HashTable()
{
}
HashTable::~HashTable()
{
//cout << "Destroyed" << endl;
}
void HashTable::add(int toAdd)
{
//elements[hash(toAdd)] = toAdd;
}
void HashTable::remove(int toDelete)
{
}
bool HashTable::search(int toSearch)
{
}
int HashTable::getSize()
{
//return size;
}
void HashTable::print()
{
}
int main()
{
return 0;
}
The C++ here is valid (once you fill in the empty functions). The problem is with how Visual C++ uses precompiled headers. When you use precompiled headers (the default setting), the Visual C++ compiler expects the first line of each implementation file to be #include "stdafx.h", and doesn't compile anything that appears before that.
This means the the include of <vector> in your code is ignored, and thus compiling vector<int> causes an error.
If you move the line #include "stdafx.h" to the top this should compile. Or you can disable precompiled headers in the project settings.