Storing a string into a Queue, using seperate class definitions, C++ - c++

I am trying to store a string input (a math equation) into a Queue linked list. To add a character into the Queue, i need to access the Queue function "Enqueue( )" from inside a separate class: the "Calculate" class.
I keep getting error messages ("Queue': undeclared identifier") and ("QueObj": undeclared identifier).
My code mostly looks like this (removed most unrelated code):
#include <iostream>
#include <stdlib.h>
#include <string>
class Calculate // Convert from string to node
{
public:
double Calc(string text)
{
input = text; // math notation, user input sent from main()
/* error message here -> */ Queue queObj; // Queue object created to access Queue functions
/* error message here -> */ queObj.Enqueue(text); // Enqueues the notation into a Queue
};
private:
string input; // The input string for the math equation
};
class Queue
{
public:
void Enqueue(string queVal) // Enqueue definitions
{
// Enqueue instructions
};
void Dequeue() // Dequeue definitions
{
// Dequeue instructions
};
bool IsEmpty() // Queue size check
{
// Queue size check
};
private:
Node *head = NULL; // Pointer for start of queue (set to NULL)
Node *tail = NULL; // Pointer for end of queue (set to NULL)
friend class Calculate; // Friend class allows Calculate to access Queue private data
};
int main()
{
string Eq1 = "1 + 2"; // math equation
Calculate calcObj; // object to access calculate class functions and variables
calcObj.Calc(Eq1); // stores the equation into calculate class
return 0;
}

What is simply happening is that the class Queue is not visible to the class Calculate since the compiler (roughly speaking) reads and compiles code in top to bottom fashion. So the compiler is unaware that there exists a class named Queue while it is parsing the contents of the class Calculate.
There are two ways to make this work:
Put the class declarations at the top of all the class definitions. A class declaration looks as follows:
class Queue
{
public:
void Enqueue(string queVal); // Enqueue definitions
void Dequeue(); // Dequeue definitions
bool IsEmpty(); // Queue size check
private:
Node *head = NULL; // Pointer for start of queue (set to NULL)
Node *tail = NULL; // Pointer for end of queue (set to NULL)
friend class Calculate; // Friend class allows Calculate to access Queue private data
};
And then in the bottom, you can define all the functions as follows:
void Queue::Enqueue(string queval)
{
// Enqueue instructions
}
// rest of the functions
Create a header file with all such class declarations in it, and then include that header file. And then create a .cpp file with all the function definitions in it. While compiling the program, link both the object files (recommended option, since it is less cluttered and easily scalable).
Also, unrelated to the problem here, but you should ideally explicitly mention the return type of main as follows
int main()
This code might even not compile under newer C++ standards, because of not explicitly mentioning the return type of main.
Also, you don't need to use a semi-colon (;) after function definitions.
Lastly, format you code properly (specifically, don't use inconsistent indentations).

Related

New C++ coder w/difficulty on scope/visibility in queue example

All,
I asked a question last week and I thank you for your tolerance in answering. I'm overall an inexperienced coder but have dabbled most of my life. This is the hardest language/class I've ever taken and it's driving me nuts that I can't get some of these concepts. I've done quite a bit of googling and found some helpful things but never something quite similar enough to fix what I've run into.
ALSO: I am not that familiar with the SO interface, so wasn't sure last time how to 'mark' an answer as the best to give credit to those who helped. I didn't see a way to respond to other smaller comments. A lot in here, but I want to do the right thing for you folks taking the time to help others.
The assignment is to create a queue class with five files described as follows:
QueueItem.h contains the class definition for QueueItem
QueueItem.cpp contains the member function implementations for QueueItem.
Queue.h contains the class definition for Queue.
Queue.cpp contains the member function implementations for Queue.
main.cpp contains the main() test function.
Queue.h
#pragma once
#include "QueueItem.h"
class Queue {
public:
Queue(); // ctor inits a new empty Queue
~Queue(); // dtor erases any remaining QueueItems
void addItem(const char* pData);
void removeItem();
void print();
void erase();
private:
QueueItem* _pHead; // always points to first QueueItem in the list
QueueItem* _pTail; // always points to the last QueueItem in the list
int _itemCounter; // always increasing for a unique id to assign to each new QueueItem
};
In Queue.cpp below, there are two places where I think the code should either be _pTail->_pNext or _pTail._pNext. If it's the ->, then I get C++ member (declared at line 21 of) is inaccessible but using the . gives C++ expression must have class type. This is definitely one of the places where I think it's a conceptual thing I'm not understanding because I think it should be the -> but have no idea how to make that accessible.
Queue.cpp
#include "Queue.h"
#include "QueueItem.h"
#include <iostream>
using namespace std;
void Queue::addItem(const char* pData) {
// dynamically create and init a new QueueItem object
QueueItem* pItem = new QueueItem(pData, ++_itemCounter);
if (0 == _pHead) // check for empty queue
_pHead = _pTail = pItem;
else {
// link new item onto tail of list using _pTail pointer
_pTail->_pNext = pItem; // links the current pTail to the new pItem
_pTail = pItem; // move the pTail to the new item
}
}
void Queue::removeItem() {
// check for empty queue
if (0 == _pHead)
{ // if empty, nothing to do
}
else
{
// pop top item off
QueueItem* popped = _pHead; // create popped to hold value of _pHead
_pHead = popped->_pNext; // Move the pHead to the next in queue
delete popped; // delete the popped value
--_itemCounter; // decrement counter
}
}
QueueItem.h
#pragma once
#include "Queue.h"
class QueueItem {
public:
QueueItem(const char* pData, int id); // ctor
void setNext(QueueItem* pItem);
QueueItem* getNext() const;
int getId() const;
const char* getData() const;
private:
char _data[30]; // data value (null terminated character string)
const int _itemId; // unique id for item in queue
QueueItem* _pNext; // next item in queue
};
In QueueItem.cpp below, the ctor is not right. The error C++ no instance of overloaded function matches the specified type comes up and I'm not sure why. It seems like the call matches the definition?
QueueItem.cpp
#include "QueueItem.h"
#include <cstring>
#include <string>
QueueItem::QueueItem(char* pData, int id) // ctor
: _itemId{ id } // Initialization list
{
strcpy_s(_data, pData);
_pNext = NULL;
}
void QueueItem::setNext(QueueItem* pItem)
{
_pNext = pItem;
}
QueueItem* QueueItem::getNext() const
{
return _pNext;
}
int QueueItem::getId() const
{
return _itemId;
}
const char* QueueItem::getData() const
{
return _data;
}
main.cpp
#include <iostream>
#include <conio.h>
#include "Queue.h"
using namespace std;
// note - you may need to change the definition of the main function to
// be consistent with what your C++ compiler expects.
int main() {
char anykey;
Queue myQueue;
myQueue.removeItem();
myQueue.addItem("red");
myQueue.addItem("green");
myQueue.addItem("blue");
myQueue.addItem("orange");
myQueue.print(); // print contents of queue (item ID and data)
myQueue.removeItem();
myQueue.removeItem();
myQueue.removeItem();
myQueue.removeItem();
myQueue.print();
myQueue.erase();
myQueue.addItem("olive");
myQueue.addItem("mauve");
myQueue.addItem("purple");
myQueue.print();
myQueue.erase();
myQueue.print();
cout << "Press any key...";
anykey = getch();
return 0;
}
Let's walk through this in order.
Queue.h
#pragma once
#include "QueueItem.h"
You don't actually use the definition of the QueueItem in this header, you only mention pointers to it. To have a pointer to a type (without ever dereferencing it - in the header, that is) - we just need to know the type exists.
So, you can replace the include with the forward declaration
class QueueItem;
And break the cycle between the two header files. (You will now need to include QueueItem.h in Queue.cpp though, because you actually do use it there).
You actually don't need to include Queue.h in QueueItem.h either, because it isn't used at all.
In Queue.cpp below, there are two places where I think the code should either be _pTail->_pNext or _pTail._pNext.
Yep, your first thought was correct.
If it's the ->, then I get C++ member (declared at line 21 of) is inaccessible
The word "inaccessible" tells us that the problem with _pTail->_pNext is that QueueItem::_pNext is declared private. Only methods of the QueueItem class (or friends) itself are allowed to access its private members.
You could add a friend declaration to QueueItem to let Queue have privileged access to its private parts. But, as you already have a public accessor, you can just write _pTail->getNext() instead.
but using the . gives C++ expression must have class type.
This is because only class (and struct, and union) objects have members. You have a pointer to a class object, so -> is the right choice. If it helps to remember, p->member is essentially the same as (*p).member ... it's just nicer to type.
In QueueItem.cpp below, the ctor is not right. The error C++ no instance of overloaded function matches the specified type comes up and I'm not sure why. It seems like the call matches the definition?
These two are not the same:
QueueItem(const char* pData, int id);
QueueItem::QueueItem( char* pData, int id) { ... }
I try to just copy & paste lines like this where possible - there's no benefit in doing more typing, with more opportunity for mistakes, and it's sometimes hard to see these simple errors when you know what you intended to write.

Attempting to reference a deleted function (No reference to a funciton made)

I'm experiencing a problem at the moment where apparently I am Attempting to reference a deleted function. As far as I can see, I'm not actually referencing a function but a smart pointer to a struct.
This is a university project whereupon multiple header files and CPP files are being used to allow us to understand how to use multiple files in the same project and link them together along with understanding and making use of polymorphism. We are using multiple files as the brief states we must. The files and definitions were provided for us.
The following is supposed to conduct a "Breadth-first" search on a terrain map (array of numbers ranging from 0-3) from a starting location to the goal location. It is about path-finding.
This is what I have so far:
#include "SearchBreadthfirst.h" // Declaration of this class
#include <iostream>
#include <list>
using namespace std;
bool CSearchBreadthFirst::FindPath(TerrainMap& terrain, unique_ptr<SNode> start, unique_ptr<SNode> goal, NodeList& path)
{
// Initialise Lists
NodeList closedList; // Closed list of nodes
NodeList openList; // Open list of nodes
unique_ptr<SNode>currentNode(new SNode); // Allows the current node to be stored
unique_ptr<SNode>nextNode(new SNode); // Allows the next nodes to be stored in the open list
// Boolean Variables
bool goalFound = false; // Returns true when the goal is found
// Start Search
openList.push_front(move(start)); // Push the start node onto the open list
// If there is data in the open list and the goal hasn't ben found
while (!openList.empty() || goalFound == false)
{
cout << endl << "Open list front:" << openList.front() << endl;
currentNode->x = openList.front()->x;
currentNode->y = openList.front()->y;
currentNode->score = openList.front()->score;
currentNode->parent = openList.front()->parent;
}
}
It's highlighting this line: currentNode->x = openList.front()->x; as the problem.
The NodeList type is defined in SearchBreadthfirst.h as the following:
using NodeList = deque<unique_ptr<SNode>>;
SNode is also defined in SearchBreadthfirst.h as such:
struct SNode
{
int x; // x coordinate
int y; // y coordinate
int score; // used in more complex algorithms
SNode* parent = 0; // note use of raw pointer here
};
The program breaks upon build. I've been trying to wrap my head around this for days now, so any help is greatly appreciated. If I've missed anything out, let me know and I'll add it in!
James
The error message Attempting to reference a deleted function is due to the fact that std::unique_ptr explicitly deletes its copy constructor because, obviously, there's only supposed to be one copy of the pointer it contains.
When you call
openList.push_front(start);
You're creating a copy of start which is of type unique_ptr<SNode> and it has a deleted copy constructor. In order to use a std::unique_ptr with a container, you need to move the object into the container. You need to do something like this:
openList.push_front(move(start));
That will move start into the deque and move what was in there into start.

Friend classes need to include or forward declare c++?

I have been struggling with errors when trying to build a binary tree using a queue. The problem is what classes should include what files and how to reference objects from the other classes? I threw my files into an IDE in an attempt to pinpoint just what the problems are and the results are below. Currently my issue is that in the Queue.h file, treePtr "does not name a type". You can see the evolution of this problem here This question is different from other posts because the two classes are friend classes. This brings up the problem of circular dependencies. I have tried all sorts of combinations of including files and forward declaring but one combination causes one type of issue, and another creates different errors.
Here is the main class:
#include <cstdlib>
#include "Tree.cpp"
using namespace std;
int main() {
Tree tree;
tree.addTreeNode(5);
return 0;
}
Here is the Queue.h:
#ifndef QUEUE_H_
#define QUEUE_H_
class Tree; //Was instructed to put this here
class Queue {
friend class Tree;
private:
typedef struct node {
Tree::treePtr treeNode; //Here is the problem
node* next;
}* nodePtr;
nodePtr head;
nodePtr current;
public:
Queue();
virtual ~Queue();
void push(Tree::treePtr t); //Here is the problem
int pop();
void print();
};
#endif /* QUEUE_H_ */
This is Tree.h:
#ifndef TREE_H_
#define TREE_H_
#include "Queue.h" //Was instructed to put this here
class Tree {
friend class Queue;
private:
Queue q; //Edit: Most likely problem since Queue and Tree are friends
typedef struct tree {
int data;
tree* left;
tree* right;
}* treePtr;
treePtr root;
int numNodes;
public:
Tree();
virtual ~Tree();
void addTreeNode(int integer);
};
#endif /* TREE_H_ */
This is tree.cpp
#include <cstdlib>
#include <iostream>
#include "Tree.h"
using namespace std;
Tree::Tree() {
root = NULL;
numNodes = 0;
}
void Tree::addTreeNode(int integer) {
numNodes++;
treePtr t = new tree;
t->left = NULL;
t->right = NULL;
t->data = integer;
cout << "add root\n";
root = t;
q.push(t); //This is a problem
q.print();
}
Tree::~Tree() {
// TODO Auto-generated destructor stub
}
You have to compile Tree.cpp and (I suppose you have one) Queue.cpp separately, instead of including Tree.cpp in your main.cpp.
Forward declarations are fine for friending classes, even if you do so circular.
Put #include "Tree.h" in your Queue.cpp file, to let the compiler see the full declaration.
In main.cpp just put #include " Tree.h".
To get the final executable link all of the produced object files main.o(bj), Tree.o(bj) and Queue.o(bj).
See also [Why should I not include cpp files and instead use a header?] please.
As I've noticed now your actual problem is, you cannot access nested classes/structs from a forward declared class/struct as you're requiring with accessing treePtr from Queue (treePtr should be better named something like TreeNode or similar BTW).
You cannot make treePtr a private nested type in this case, it must be publicly visible.
A viable way is to put treePtr in a namespace internal_, that indicates it's not intended for usage outside the API.
Another viable way is to make Queue a template class, that accepts any type of tree or other kind of nodes. Since can't see any use case, why Queue needs to know about the internal specifications of tree (besides the trivial stuff like copying aso.), it's not really necessary to make Queue a friend class.
My best guess here is that the problem was that since the classes Queue and Tree were friends, and Tree had an instance of a Queue as a data member, there was some conflict when trying to include files and forward declare. By sharing data members with Queue, the Tree class shared an instantiation of a Queue object with the Queue class, so there was some inception sharing going on that was not obvious. #πάντα ῥεῖ suggested to make the Queue a template class so that it could accept objects of any type, without having to couple with the Tree (which was done so the Queue class would know what to do with treePtr objects). Making Queue a template class solved the problem because now the Tree class can have an instance of a Queue, and I can pass objects of type treePtr to the Queue without the Queue knowing anything about the Tree class before hand.

c++ store items into an array

I have this code that in my mind, it recieved an item called Vehicle and it has to store it in an array called Node. This is the code related to this part of the program:
void Table::process(Vehicle v, int cont) {
char a='A'+cont;
putVehicle(a,v);
Node.a_v[cont]=v;
if(cont==0) a_surt=v.rowVehicle();
}
This is how I have the array on the private part of Table.h:
struct Node{
Vehicle a_v;
};
The error I get is:
error: expected primary-expression before '.' token
I have the includes I need, but everytime I type this: Node.a_v It gives me that error.
Any advice?
If you want to use a struct, you need to declare a Node before using it. Also, the struct needs to contain an array (or better, look into vectors for more flexibility).
struct Node {
Vehicle[10] a_v; // 10 is max number of Vehicles in array
};
Node myNode;
myNode.a_v[cont] = v;
Remember that if you want to keep this Node around and put more things in it, it needs to be declared in the right scope. For example, to have your process function add a Vehicle to a Node that exists outside of the function process, you could something like this:
void Table::process(Node n, Vehicle v, int cont) {
char a = 'A'+cont;
putVehicle(a,v);
if (cont < 10) {
n.a_v[cont] = v;
}
if (cont == 0) a_surt = v.rowVehicle();
}
It kind of looks like you're just trying to use an array. In that case you're looking for something like this:
// This would go somewhere in your program. Again, 10 is just an example.
Vehicle vehicleArray[10];
// Send this array to this function
void Table::process(Vehicle[] vArray, Vehicle v, int cont) {
char a = 'A'+cont;
putVehicle(a,v);
if (cont < 10) { // In a real program, don't hard-code array limits.
vArray[cont] = v;
}
if (cont == 0) a_surt = v.rowVehicle();
}
You should use Node object to get access to the a_v variable. This line
Node.a_v[cont]=v;
Is incorrect. You should do something like that:
Node n;
n.a_v[cont]=v;
everytime I type this: Node.a_v It gives me that error.
Node is a type; types define the structure of a objects, but they do not have fields of their own (except the static fields, which belong to all instances at once; they are accessed differently anyway).
In order to use a . or -> operator, you need an instance of a Node, like this:
Node x;
x.a_v = ...
It is not clear in your case from where the Node instances should be coming, though. In order to access them, you would need to either pass them in as parameters, or make them available statically/globally (not recommended).
Okay, so Node is NOT the name of your array. It's the name of a user-defined type that is supposed to contain an array. Your Node, however, does not contain an array. It contains one Vehicle, named a_v. I assume a_v is supposed to represent an Array of Vehicles. Therefore, you need to allocate the array. Something like this:
struct Node {
Vehicle a_v[AMOUNT];
};
If you don't know at compile-time how large you want your arrays to be, then they must be dynamically allocated, like this:
struct Node {
Vehicle* a_v;
Node() {
a_v = new Vehicle[AMOUNT];
}
};
If it's dynamically allocated, then it must also be deallocated:
struct Node {
Vehicle* a_v;
Node() {
a_v = new Vehicle[AMOUNT];
}
~Node() {
delete[] a_v;
}
};
AND if it's dynamically allocated, you need to add provisions for copying or disable copying:
struct Node {
Vehicle* a_v;
Node() {
a_v = new Vehicle[AMOUNT];
}
~Node() {
delete[] a_v;
}
// Disable copies (with C++11 support):
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
// Disable copies (without C++11 support) by making them private and not defining them.
private:
Node(const Node&);
Node& operator=(const Node&);
};
Then to access one of the Vehicles, you'd need to do so like this:
Node n; // Declare a node, which contains an array of Vehicles
n.a_v[cont] = v; // Copy a Vehicle into the array of Vehicles
Note, however, that if you declare the Node instance in this function, then it is local and it will go out of scope as soon as your function ends. You need to declare the Node instance as a member of your Table if you want it to persist past the function call.
class Table
{
private:
Node n;
};
Lastly, as others have suggested, I'd highly recommend that you read a C++ book to learn C++. My personal recommendation is this book (5th edition, don't buy 6th or 7th - the author of those editions is terrible).

c++ class constructors automatically mapping objects to an event handler

I'm currently working on a little project for my beaglebone. Essentially the goal is to create a framework which gives the full power of c++ as opposed to the beaglebone's stock javaScript framework, but is also as easy to use for the developer as the arduino framework is.
One of the things i've built are premade classes for different types of simple GPIO interrupts like buttons, rotary encoders, etc, so the developer just has to define a button, and tell it which GPIO pin on the beaglebone it's connected too.
Right now I have to manually add the interrupt object's pollInterupt() function to the main loop so the program can repeatedly check the state of the inerupts GPIO pin.
Here is the problem: I want to add code to the button's class constructor function, that when defined, will automatically pass itself to an interrupt handler behind the scene to repeatedly run the new object's pollInterupt() function, so the developer never has to do anything more complicated than defining the button.
I seem to be hitting a brick wall though. Trying to make the framework simple for the end user, is meaning that the code behind the scene is getting stupidly complicated. The best way i could think of automatically handling the defined interrupt objects, is a link list. This is what the prototype code is looking like at the moment.
#include <iostream>
class interuptButton;
class interuptHandler;
class interuptHandler{
public:
class node{
public:
node *next;
node *prev;
public:
void *interupt;
};
node *first;
node *last;
node *current;
node *temp;
public:
interuptHandler(){
first = new node;
last = new node;
first -> prev = NULL;
first -> next = last;
last -> prev = first;
last -> next = NULL;
}
void add(void *_interupt){
temp = new node;
current = last -> prev;
current -> next = temp;
temp -> prev = current;
temp -> next = last;
last -> prev = temp;
temp -> interupt = _interupt;
}
void run(){
current = first -> next;
while(current -> next != NULL){
std::cout << current -> interupt << std::endl;
// std::cout << current -> interupt -> pin << std::endl;
// current->interupt->pollInterupt();
// std::cout << reinterpret_cast < interuptButton* > (current->interupt)->pin << std::endl;
current = current -> next;
}
}
}handler;
class interuptButton{
public:
int pin;
bool value;
public:
interuptButton(int _pin){
pin = _pin;
handler.add(this);
}
void pollInterupt(){
std::cout << "check pin " << pin << " to see if the GPIO has changed" << std::endl;
}
};
int main(int argc, char **argv){
interuptButton buttonA(41);
interuptButton buttonB(45);
interuptButton buttonC(43);
handler.run();
return 0;
}
The system seems to be working, and the interuptButton constructor is successfully passing the newly created objects to the interuptHandler's link list, which it can then print the memory address for in the run() function with the output:
bin/./test
0x7fff5fbff9e0
0x7fff5fbff9d0
0x7fff5fbff9c0
The problem is when I uncomment any of the other lines in run(), where i try to access the pointer object's variables or functions, g++ starts throwing errors.
The first two lines return:
src/main.cpp: In member function ‘void interuptHandler::run()’:
src/main.cpp:47: error: ‘void*’ is not a pointer-to-object type
make: *** [all] Error 1
and the third line returns:
src/main.cpp:49: error: invalid use of incomplete type ‘struct interuptButton’
src/main.cpp:4: error: forward declaration of ‘struct interuptButton’
make: *** [all] Error 1
Any advice on how to access those objects variables and functions via their pointers would be much appreciated.
Better yet, if anyone has a better way to automatically send objects to a behind the scene event handler, I'm all ears.
In the node structure, the interrupt pointer is a pointer to void which means that it can point to any type. However, the compiler doesn't know what it points to, so you have to tell the compiler what type it really points to by using typecasting:
reinterpret_cast<interuptButton*>(current->interrupt)->pollInterrupt();
As for the other problem, you have a circular dependency. The class interruptHandler depends on the class interruptButton and the other way around. This you have to solve by separating the definition and the implementation of one or both classes. The simplest way would be to just put the interruptButton class definition above the interruptHandler definition, and place the implementation, i.e. the actual code, of interruptButton after the interruptHandler class definition.
If you want to use multiple interruptable classes, not only the interruptButton class, you should use inheritance and abstract base classes with virtual functions. Then you won't need the void pointer or typecasting:
struct baseIntertuptable
{
virtual void pollInterrupt() = 0;
};
struct interruptHandler
{
private:
struct node
{
// ...
baseInterruptable* interrupt;
};
public:
void run()
{
// ...
current->interrupt->pollInterrupt();
// ...
}
};
class interruptButton : public baseInterruptable
{
public:
void pollInterrupt()
{
// ...
}
};
This should also solve your problem with the circular dependencies of the class definitions, as the abstract base class baseInterruptable is now fully defined before it's used and the interruptHandler class only uses that one.
Do you need to start moving definitions of functions into .cpp files? Looks like you are accessing the internals of interuptbutton before its defined.
Or since it is just 1 big .cpp file, you can define the run function just before main to fix your second set of errors.
First error is self explanatory, maybe you should make a Interrupt interface and keep pointers to it, instead of to void*? reinterpret_casting just makes everything so ugly.
class IInterupt{
// other stuff common to all interupt classes
void pollInterupt() = 0; // pure virtual force all inheriting classes to implement.
}
class interuptButton : public IInterupt{ //bla bla }
class node{
public:
node *next;
node *prev;
public:
IInterupt*interupt;
};