This is the implementation of a queue class in C++. What I cant figure out is I want a function delete in which I return the deleted element, but these errors appear:
expected unqualified-id before 'delete'
expected ; at end of member declaration
When I delete the delete function, everything works fine, but not when it is there.
I'm trying to find the shortest path in an unweighted undirected graph with bfs and I need queue, specifically a queue which returns the deleted vertex.
class Queue
{
public:
Queue(int maxQueueSize):MaxSize(maxQueueSize)
{
queue=new int[MaxSize];
front=rear=-1;
}
bool isFull()
{
if(rear==MaxSize-1)
return true;
else return false;
}
bool isEmpty()
{
if(front==rear)
return true;
else return false;
}
void add(const int& x)
{
if(isFull())
return;
else
queue[++rear]=x;
}
int* delete()
{
int& x;
if(isEmpty())
return 0;
else
{
x=queue[++front];
}
return x;
}
private:
int front,rear;
int* queue;
int MaxSize;
};
'delete' is a reserved keyword for C++.
See a list of reserved keywords here.
You may better call it 'remove' or something like that.
Better yet, just use a std::queue<>, it's all well written and tested for you already.
Related
I'm trying to implement a class of Circular List with a nested class of iterator and I wrote like this:
template <class T>
class CircularList {
struct Item {
T data;
Item* next;
};
Item* head;
int size;
public:
CircularList() {
head = new Item();
head->next = head;
}
int sizeList() { return size; }
void push(T data) {
Item* i = new Item();
i->data = data;
i->next = head->next;
head->next = i;
size++;
}
class CircularListIterator {
Item* p;
CircularListIterator() {
p = head->next;
}
bool hasNext() {
if(p->next != head) {
return true;
}
return false;
}
T next() {
T data_temp = p->data;
p = p->next;
return data_temp;
}
};
CircularListIterator* iterator() {
return new CircularListIterator();
}
};
int main() {
CircularList<string>* letters = new CircularList<string>;
letters->push("d");
letters->push("c");
letters->push("b");
letters->push("a");
Iterator<string>* it= new Iterator<string>;
it = letters->iterator();
while (it->hasNext()) {
cout<< it->next() << "," << endl;
}
return 0;
}
But the Iterator is not working when I try to create an iterator in the main function, It said that it wasn't declared in the scope and has no member of it.
Assuming by "in the main class" you mean in the main function, the problem is quite straightforward: you're trying to construct a ::Iterator<string>, but there is no class in the global namespace (or anywhere else, in this code sample) called Iterator! You could try constructing a CircularList<string>::CircularListIterator - that's at least a class that exists - but it wouldn't work because the iterator needs to be associated with a CircularList object for it to be able to access member variables like head.
The correct thing to do here is to promote the iterator function - the one that returns a CircularListIterator* - out of the CircularListIterator class and into the CircularList class. Then, in your main function, you can call letters->iterator() and it'll return a CircularListIterator* for the letters object.
Now, CircularListIterator doesn't inherit from any other iterator classes - neither the (nonexistent-in-this-code Iterator you've typed it as, nor the C++ std::iterator or any of its variants) - so you can't assign it to it or probably even compile the code that references Iterator. To make CircularListIterator a subclass of std::iterator, you'll need to extend std::iterator<Category, T> with the appropriate category. See https://www.cplusplus.com/reference/iterator/iterator/ for more information on the std::iterator class template, including an example of implementing it.
I would like to ask 2 question about this code. Where I just try to simulate a stack.
Stack.h
#pragma once
namespace stackandqueue {
class Stack
{
private:
int index;
int *stackdata;
public:
Stack();
~Stack();
void push(int val);
int pop();
int top();
bool isEmpty();
};
}
Stack.cpp
#include "stdafx.h"
#include "Stack.h"
namespace stackandqueue {
Stack::Stack() : index{ 0 }
{
stackdata = new int[index];
}
Stack::~Stack()
{
delete[] &stackdata;
}
void Stack::push(int val) {
stackdata[index] = val;
index++;
}
int Stack::pop() {
int val = stackdata[index];
index--;
return val;
}
int Stack::top() {
return stackdata[index];
}
bool Stack::isEmpty() {
return index == 0;
}
}
Meaning is to let me create
Stack stack;
And then it initilizes a dynamic array with 0 as first index and that let me push, pop, top values.
First question:
Why am I having unresolved symbols for method definitions?
Second question:
About 'stackdata', you find is the right way if I want to declare an "array" with dynamic size for this behaviour?
I'm open for improvements and best practices. Im used to programming languagesbut I've never delved into c ++ and I don't want to have bad practices. So you see I am taking it from the begining.
Thanks.
I post solution reached with your help that maybe helps someone.
class Stack
{
private:
int index;
int* stackdata;
public:
Stack(int size);
~Stack();
void push(int val);
int pop();
int top();
bool isEmpty();
};
Stack::Stack(int size)
: index {0}, stackdata{new int[size]}
{
}
Stack::~Stack()
{
delete[] stackdata;
}
void Stack::push(int val) {
stackdata[index] = val;
index++;
}
int Stack::pop() {
index--;
return stackdata[index];
}
int Stack::top() {
return stackdata[index-1];
}
bool Stack::isEmpty() {
return index == 0;
}
There are several problems with this.
An array, dynamically allocated or otherwise, is not a stack/queue/vector. You're creating literally 0 ints. All of your element accesses after that have undefined behaviour. You need your array to grow, i.e. be a vector, e.g. std::vector.
delete[] &stackdata has the wrong level of indirection. You meant delete[] stackdata. You were trying to delete the pointer which was not dynamically allocated.
You're missing copy/move constructors and copy/move assignment operators so as soon as you transport a Stack anywhere it will explode. (The original instance will do a delete[] on the same pointer that the copied/moved instances will!) Read about the rule of three/five/zero.
Other than that, it looks like a stack.
The problem you don't have here is an undefined reference, which is funny because that's the only one you asked about. :) If you do indeed have such a thing, it's likely a problem with your build system (failing to compile that source file), which we cannot see.
i have a program with 3classes.
first one is for defining a node(my node is an array with 9 elements) - 2nd one contains some functions - 3rd is defining a static stack(I have a stack with 100members that each member is an array with 9members)
suppose that in main(), I call one of the functions from 2nd class(for example expand() ). expand function is supposed to push a node into stack(push into UN) and update the stack pointer. After that for example I want to have access to top node of stack and pop that node using main(). but I'm successful. when I watch the UN and top node through debug tool, I see that their amount is being reset after each push(stack doesn't accept new elements). whats wrong?
here is some parts of code that is needed:
#include<iostream>
using namespace std;
#define max 100
class node
{
public:
int node_n[9];
friend class func;
friend class stack;
};
node n;
class node;
class func
{
public:
func();
void expand(node,stack);
friend class stack;
};
class node;
class stack
{
private:
int sp;//stack pointer
public:
node un[max];//saves expanded noded(children)
stack();
int isempty(); //this will show whether stack is empty or not
int isfull(); //this will show whether stack is full or not
void push(node);
node pop();
};
//****************************
stack::stack()
{
sp=-1;
}
//****************************
int stack::isempty()
{
if(sp==-1)
return true;
else
return false;
}
//****************************
int stack::isfull()
{
return sp==max-1;
}
//****************************
node stack::pop() //un=un-[n]
{
for(int k=0;k<=8;k++)
n.node[k]=un[sp].node[k];
sp--;
return n;
}
//****************************
void stack::push(node n ) //un=un+{x1....xn}
{
sp++;
for(int k=0;k<=8;k++)
un[sp].node[k]=n.node[k];
}
//****************************
void func::expand(node n,stack st)
{
if ( n.node_n[0]==0 )
{
if(n.node_n[1]==0)
{
n.node_n[0]=1;
n.node_n[1]=1;
st.push(n);
.
.
.
//******************************
int main()
{
func b;
stack st;
node n2;
node s; //initial state
node g; //goal state
for(int h=0;h<=8;h++)
{
s.node[h]=0;
g.node[h]=1;
}
//n2=s;
st.push(s);
Lable1:
n2=st.pop();
b.expand(n2,st);
goto Lable1;
system("pause");
return(0);
}
This function
void func::expand(node n,stack st)
is taking the st parameter by value, meaning that it has its own copy of st and any changes it makes will only affect that copy.
What you probably want is to pass st by reference, so that the function can make changes to the original passed in object. To do this, change the function declaration and definition to:
void func::expand(node n,stack &st)
I always seem to get in trouble when I'm deleting all nodes from a tree. I am trying to release all the memory I allocated when creating a trie tree.
I am suppose to create a function remove_all
Is it enough to delete just the "root"
something like this:
void PrefixStringSet::remove_all(NodePtr node)
{
delete root;
}
Or do I have to delete each node with something like this:
void PrefixStringSet::remove_all(NodePtr node)
{
if(!root)
{
return;
}
remove_all(root->children);
delete root;
}
Obviously neither of these are working or I wouldn't be here :).
Other question. Do I have to call the remove_all function in my main function if my destructor is implemented like this
PrefixStringSet::~PrefixStringSet()
{
remove_all(root);
}
Or does the destructor automatically delete the trees/nodes I create?
Edit
struct TrieNode
{
TrieNode(bool present = false);
bool is_leaf();
bool present;
TrieNode* children[ALPHABET_SIZE];
};
class PrefixStringSet
{
public:
// Creates an empty prefix string set.
PrefixStringSet();
~PrefixStringSet();
bool insert(string s);
bool contains(string s);
private:
NodePtr root;
void remove_all(NodePtr node);
};
typedef TrieNode* NodePtr;
Deleting only root is not enough: when deleting a root, you should check whether its children aren't empty, and if they are not empty, recursively delete them. C++ doesn't have garbage collector to do the work for you :)
If your remove_all method is within the destructor of the wrapper object, then you don't have to call it separately.
You should write a remove method in all classes you want to delete at runtime.
So you can delete a tree with little care about garbage collection.
It's easy to use pointer in this way:
class a
{
public:
a(){}
~a(){remove();}
init(int v){
var = new int;
*var=v; }
remove(){delete var;}
private:
int *var;
};
class b
{
public:
b(){}
~b(){remove();}
init(int v){
var = new a;
var->init(v); }
remove(){
var->remove();
delete var; }
private:
a *var;
};
To answer your question: No, deleting root is not enough.
edit: sry i made a mistake at a:init(). I forgot to derefer the pointer.
In Cpp:
void deleteAll(Node* curNode) {
for (int i = 0; i < 26; i++) {
if (NULL != curNode->child[i]) {
deleteAll(curNode->child[i]);
}
}
delete curNode;
}
deleteAll(root);
Currently working on an assignment for my datastructures class in university using stacks with dynamic memory allocation. Currently I'm getting a compile error C3867 saying I'm missing a function call from an argument list. I'm not really understanding where this error is coming from / I'm having trouble identifying what exactly is my error in my code; so I was wondering if someone might be kind enough to explain to me what it is, and maybe a friendly tip to remember so I can not have this happen again.
also, I apologize for the poor formatting, I've never posted here before sorry if its hard to read. :(
code posted below.
Thanks, and regards. :P
Header File:
#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <iomanip>
struct Node
{
Node *nextPtr;
int value;
};
class Stack
{
public:
//Constructors and Deconstructers Here
Stack(); //Default Constructor
~Stack(); //Default Deconstructor
//logical methods || functions here
bool isEmpty(void); //prototype checks if stack is empty
//stack operations || function prototypes here
void push(int); //prototype to push values of type int onto the stack
int pop(); //prototype to pop values off of the stack and return a value
int top(); //prototype to return the top value
private:
Node *topPtr; //pointer to class Node Object, specifically for the top of the stack
};
#endif
Class File:
#include "CPTN278_A3_Stack_Arsenault.h"
using namespace std;
Stack::Stack()
{
topPtr = 0; //set the top pointer equal to zero.
}
Stack::~Stack()
{
while (!Stack::isEmpty())
{
Stack::pop();
}
}
bool Stack::isEmpty()
{
if(top == 0)
{
return true;
}
else
{
return false;
}
}
void Stack::push(int valueTMP)
{
Node *itemPtr = new Node;
itemPtr->nextPtr = topPtr;
itemPtr->value = valueTMP;
topPtr = itemPtr;
return;
}
int Stack::pop()
{
int returnValue; //unintialized int
Node *itemPtr; //unintialized pointer to node
returnValue = topPtr->value;
itemPtr = topPtr;
topPtr = itemPtr->nextPtr;
delete itemPtr;
return returnValue;
}
int Stack::top(void)
{
return topPtr->value; //**this is where my error is being thrown**
}
bool Stack::isEmpty()
{
if(top == 0) // <-- here is the problem
{
return true;
}
else
{
return false;
}
}
top is a function, to check its result you need top(). But I think you should be testing topPtr instead.
Before you had:
bool Stack::isEmpty()
{
if(top == 0) <-- top is a function, did you mean 'topPtr'?
{
return true;
}
else
{
return false;
}
}
Fix:
bool Stack::isEmpty()
{
return topPtr == 0;
}
That's your only build error. I'm not sure why you or the compiler thought it was in the top method. That's perfectly fine. Also there's no need to write:
if (expression_that_is_true_or_false)
return true;
else
return false;
Just do:
return expression_that_is_true_or_false;
I might be borderline preaching style here, but try to get used to understanding expressions this way. Expressions involving logical operators like ==, !=, &&, ||, <, >, etc. evaluate to true or false, so there is no need to do conditional branching only to then return what the expression originally evaluated to in the first place.
Oh and I realize this is homework, but check out std::stack later in your free time if you haven't already.
In function Stack::isEmpty(), something wrong with top.
bool Stack::isEmpty()
{
if(top == 0) // here
{
return true;
}
else
{
return false;
}
}
I think it should be as below:
if(topPtr==0)
...