Problems accessing private data members c++ - c++

I have three files: Stack.cc, Stack.h and stacktest.cc . I am not sure about which files to include where, and i am getting different errors because of it. Currently, the code from Stack.h is:
#ifndef STACK_H
#define STACK_H
#include<iostream>
using namespace std;
template<typename T>
class Stack
{
public:
Stack();
void push(int);
void pop();
int top();
int size();
bool empty();
private:
class Element
{
public:
int data;
Element *next;
Element(Element *n, T d) : next{n}, data{d} {}
};
Element *first;
int num;
};
#endif
#include"Stack.cc"
the (relevant, i think) code from Stack.cc is:
#include<iostream>
using namespace std;
template<typename T>
Stack<T>::Stack()
{
first=nullptr;
}
template<typename T>
void Stack<T>::push(int)
{
num++;
first = new Element(first, data);
}
Stacktest is currently just a test file attempting to call the default constructor. The errors i currently get are:
In file included from Stack.h:30:0,
from stacktest.cc:2:
Stack.cc: In member function ‘void Stack<T>::push(int)’:
Stack.cc:22:28: error: ‘data’ was not declared in this scope
first = new Element(first, data);
^
Stack.cc: In function ‘int size()’:
Stack.cc:62:11: error: ‘num’ was not declared in this scope
return num;
For some reason it wont let me access private data members. Before i didnt have the include in the .h file and instead included the .h in Stack.cc, and that worked, although wouldnt let me access the stack class from Stacktest.cc(Stacktest.cc just includes Stack.h)
Any help would be greatly appreciated, thanks.

Related

Understanding how imports are working in C++

I'm trying to understand how including works in C++. I have two questions about it. The first one is on how properly import the .h file. For example I created the following HashNode.h file:
namespace HashNode{
template<class Data>
class HashNode{
private:
Data data;
HashNode *next;
public:
explicit HashNode(const Data &data);
Data getKey();
~Node();
};
}
So in the HashNode.cpp file, it should like:
#include "HashNode.h"
using namespace HashNode;
template <class Data> // ~~~ HERE 1 ~~~
HashNode::HashNode(const Data &data) {//todo};
template <class Data> // ~~~ HERE 2 ~~~
Data* HashNode::getKey() {
//todo
}
HashNode::~Node() {
//todo
}
This way it works but do I have to include template <class Data> beside each function which uses Data? Why it does not recognize Data without including template <class Data>?
Also I have created the Hash.h file which should use the HashNode.h file:
#include "HashNode.h"
using namespace HashNode;
namespace Hash {
template <class Data>
class Hash {
typedef enum {
GOOD = 0,
BAD = -1,
BAD_ALLOC = -2
} Status;
private:
HashNode **hash;
int capacity;
int size;
public:
explicit Hash(int size);
Status insertData(const Data &data);
~Hash();
};
}
But I get the the following error: Can't resolve type 'HashNode'. Why it can't see the import?
In the Hash.cpp file I get Unused import statement for #include "HashNode.h". Why is that?
Also, what if I want to include private functions - should them be in the .h file or in the .cpp file?
The member functions of a template class are themselves also templates. Because of this, they need to be defined with any required template parameters and template type definitions.
About your second question, it has to do with namespaces. As I see it, having namespace and class under the same naming might cause you ambiguity. Although, everything seems to be fine on the structural side of the code. Try using #pragma once or some kind of guards to prevent this kind of issues.

Possible Inheritance Scope Issue:

I have an Array class that is inheriting from BaseArray class. In BaseArray, I have the protected member variables data_ and cur_size_. The Array class introduces a resize function. The problem I am encountering is that none of the protected member variables from BaseArray are seeming to be accessed in the resize function.
EDIT: Solved the max_size_ problem, but the cur_size_ and data_ file persists
Inheritance? Scope? Help?
The Error:
In file included from Array.h:41:0,
from driver.cpp:6:
Array.cpp: In member function ‘void Array<T>::resize(size_t)’:
Array.cpp:29:5: error: ‘data_’ was not declared in this scope
data_=data_;
^
Array.cpp:30:18: error: ‘cur_size_’ was not declared in this scope
if (new_size>cur_size_)
^
Array.cpp:37:5: error: ‘cur_size_’ was not declared in this scope
cur_size_=new_size;
^
The Code:
BaseArray.h:
#ifndef _BASEARRAY_H_
#define _BASEARRAY_H_
#include <cstring>
template <typename T>
class BaseArray
{
public:
/// Type definition of the element type.
typedef T type;
//constructors, destructor and methods…
protected:
/// Pointer to the actual data. m
char * data_;
/// Current size of the BaseArray.
size_t cur_size_;
};
#include "BaseArray.inl"
#include "BaseArray.cpp"
#endif // !defined _BASEARRAY_H_
Array.h:
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include <cstring>
#include "BaseArray.h"
template <typename T>
class Array: public BaseArray<T> //inheriting from BaseArray
{
public:
/// Type definition of the element type.
typedef T type;
/// Default constructor.
Array (void);
Array (const Array & arr);
/// Destructor.
~Array (void);
const Array & operator = (const Array & rhs);
void resize (size_t new_size);
private:
size_t max_size_; //introduces max_size
};
#include "Array.inl"
#include "Array.cpp"
#endif // !defined _ARRAY_H_
Array.cpp:
#include "BaseArray.h"
#include "Array.h"
#include <stdexcept>
#include <iostream>
template <typename T>
Array <T>::Array (void): BaseArray<T>()
{
std::cout<<"Array def const called"<<std::endl;
}
template <typename T>
Array <T>::Array (const Array & array): BaseArray<T>(array)
{
}
template <typename T>
Array <T>::~Array (void)
{
}
template <typename T>
void Array <T>::resize (size_t new_size)
{
this->data_= this->data_;
if (new_size>this->cur_size_)
{
max_size_ = new_size-this->cur_size_-1;
this->cur_size_=new_size;
for (max_size_; max_size_<=new_size; max_size_++)
this->data_[max_size_]=0;
}
this->cur_size_=new_size;
}
/* Also tried it like this:
template <typename T>
void Array <T>::resize (size_t new_size)
{
BaseArray<T>::data_= BaseArray<T>::data_;
if (new_size>BaseArray<T>::cur_size_)
{
max_size_ = new_size-BaseArray<T>::cur_size_-1;
BaseArray<T>::cur_size_=new_size;
for (max_size_; max_size_<=new_size; max_size_++)
BaseArray<T>::data_[max_size_]=0;
}
BaseArray<T>::cur_size_=new_size;
} */
regarding the first error, you have no max_size() member declared in Array.
regarding the second error, name lookup in templates follows a two stage logic, where non dependent expressions are looked up at definition point, whereas dependent expressions are looked up at instantiation point;
This means that when the compiler sees data_ it thinks it's a variable located somewhere else; at best, it won't find it giving you an error, at worst, it will give you the wrong variable !
In order to solve the problem, you need to make that a dependent expression, the most obvious way being replacing all data_ with this->data_, etc...
regarding your code organization, define your templates into a single header file; if you really want to split member implementations place them in a single file with a sensible file extension ( inl is ok, cpp is not )...

C++: Compile Error: expected initializer before ‘<’ token

This is a homework related question, but the compiler issue isn't the homework, I've already implemented the function I needed to write, just need to figure out this compiler error now.
I've tried searching and so far the results I get which come close to my question don't fit what causes my compiler error.
From binaryTree.h :
#include <iostream>
#include "orderedLinkedList.h"
using namespace std;
// Definition of the Class
template <class elemType>
class binaryTreeType
{
[rest of definition]
public:
[rest of declarations]
void createList(orderedLinkedList<elemType>& list);
[rest of declarations]
private:
void inorderToList(nodeType<elemType> *p, orderedLinkedList<elemType>& tList) const;
[.... then the definitions]
template <class elemType>
void bSearchTreeType<elemType>::createList(orderedLinkedList<elemType>& tList)
{
inorderToList(this->root, tList);
}
// copies to list
template <class elemType>
void bSearchTreeType<elemType>::inorderToList(nodeType<elemType> *p,
orderedLinkedList<elemType>& tList) const
{
if (p != NULL)
{
inorder(p->lLink);
tList.insert(p->info);
inorder(p->rLink);
}
}
I receive the errors :
binaryTree.h:250: error: expected initializer before ‘<’ token
binaryTree.h:257: error: expected initializer before ‘<’ token
The function definitions for createList() and inorderToList() are the ones are line 250 and 257 respectively. So I'm a little confused as to what I'm doing wrong here, and sure it's something simple.
Ok, figured out what I was doing wrong.
I originally had the template in a derived class (bSearchTreeType) and forgot to update the method definitions when I moved it into the parent class.
So the new code (line 250 and 257):
template <class elemType>
// below is 250
void binaryTreeType<elemType>::createList(orderedLinkedList<elemType>& tList)
{
[... same as in original post]
}
template <class elemType>
// below is 257
void binaryTreeType<elemType>::inorderToList(nodeType<elemType> *p,
orderedLinkedList<elemType>& tList) const
{
[... same as in original post]
}

error: ‘List’ is not a template type

I am a beginner in c++ so please excuse me if I my mistakes below turn out to be silly. Still, I am stuck with my code and would appreciate any help.
I get the following error when trying to compile through make via g++:
In file included from A.cpp:2:
List.h:20: error: ‘List’ is not a template type
A.cpp: In member function ‘void A::NowyObiekt(int)’:
A.cpp:6: error: ‘list_a’ was not declared in this scope
make: *** [A.o] Error 1
My code is separated into the following tiny files:
A.h : http://pastebin.com/QQ04xx2j (header)
A.cpp : below
#include "A.h"
#include "List.h"
void A::NewObject(int i)
{
list_a.Add(i);
}
int A::Compare(int a, int b)
{
if ( a>b ) return 1;
if ( a<b ) return -1;
else return 0;
}
List.h : below (header)
#ifndef LIST_H
#define LIST_H
template<typename T>
class Node
{
Node()
{
nxt = pre = 0;
}
Node(const T& el, Node *n = 0, Node *p = 0 )
{
dana = el; nxt = n; pre = p;
}
T dana;
Node *nxt, *pre;
};
template<typename T>
class List
{
public:
List()
{
head = tail = 0;
}
void Add(const T&);
protected:
Node<T> *head,*tail;
};
#endif
List.cpp : http://pastebin.com/a3HQ9yZ4
prog.cpp : below (main)
#include "List.h"
#include "A.h"
int main()
{
int i = 5;
class List list_a;
class A obj;
obj.Add(i);
}
and the makefile is : http://pastebin.com/GTR5jW54
As noted, I am still a beginner, so please be understanding. I would be thankful for any help and clear explanations. Thanks in advance.
There are a couple of problems with your code: The first is that you don't declare any variable named list_a anywhere. That error should be pretty obvious. The other is that you use the List class without giving it template parameters.
And last a small note about your question: As your files are indeed very small, you could put them in the question and not link to them.
Edit: About the List template problem.
You already use Node properly in List, i.e. declare the nodes as Node<T>. When you use List you simply has to do the same. For example, to declare a list of integers:
List<int> my_int_list;
Also, as you only use public functions in List from the class A, you don't need the friend declaration. If you do need to use protected or private members (which IMO is a sign of bad design) you need to make that friend-declaration templated as well:
friend class List<sometype>;
And finally, your code will not compile anyway... The reason being that when you are using a template-class, the whole class has to be fully defined (i.e. complete with its function implementations). You can solve this by putting the functions in the header file. And when defining the functions, you need the template parameter there as well:
template<typename T>
void List<T>::Add(const T& el)
{
Node<T>* head = new Node<T>(el);
if ( Compare(el,i) > i )
std::cout << "Ok" << std::endl;
}
Note that I added the template parameter in a couple of places.

Error: expected unqualified-id before ‘<’ token

I am trying to make some sort of templated Queue class. It seems ok but I am getting 2 errors in the same line which I can't figure out why. The errors appear in the implementation file .cpp where I am trying to give the definition for the destructor. Here is the code of the header file of the class:
#ifndef QUEUETP_H_INCLUDED
#define QUEUETP_H_INCLUDED
template <class T>
class QueueTp
{
private:
struct Node { T item; struct Node * next;};
enum {QSIZE = 10};
//Queue's head
Node *head;
//Queue's tail
Node *tail;
int size;
int maxsize;
QueueTp(const QueueTp & q);
QueueTp & operator=(const QueueTp & q) { return *this;}
public:
QueueTp(): size(0),head(0),tail(0),maxsize(QSIZE) {};
QueueTp(int q = QSIZE): size(0),head(0),tail(0),maxsize(q) {};
~QueueTp();
bool isEmpty(){return size==0;}
bool isFull() {return size==maxsize;}
int sizecur() {return size;}
bool push(const T& t);
bool pop(T& t);
};
#include "QueueTp.cpp"
#endif // QUEUETP_H_INCLUDED
And here is the definition of the destructor in the implementation file:
#include "QueueTp.h"
#include <iostream>
using namespace std;
typename <class T> //<-<-<- in this line I am getting the two errors
QueueTp<class T>::~QueueTp()
{
Node *ptr;
cout<<endl<<"Deleting the queue...";
while (head !=NULL)
{
ptr = head->next;
delete head;
head = ptr;
}
}
//......other method definitions
The errors are pointed above and the specific error messages I get from the compiler are the ones below.
error: expected nested-name-specifier before ‘<’ token|
error: expected unqualified-id before ‘<’ token|
||=== Build finished: 2 errors, 12 warnings ===||
Please use "template" instead of "typename" on the line where you are getting the two error messages! I find that most of the time, an unidentified keyword or a real keyword in the wrong place often gives errors similar to an undefined type, the next symbol after it would cause an error.