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;
};
Related
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).
I'm trying to pass in a head node to a function that recursively deletes everything from the LLL. But I'm not very good with classes. I've got one class for the LLL data called Node, and another called NodeList which manages all of the nodes.
The problem is that I can't access the private fields and I don't know how to get them in there. Because I don't want them public like a struct.
C++ Having trouble with syntax, so a class can pass data to other classes I've checked this link which said to make sure to have in the NodeList class Node * head, but I already have that.
C++ passing private data to other private functions in a class And I checked this one, but it was way over my head for the little C++ I know. Also I think this was just a pass by refrence issue.
This isn't the whole thing by the way, just the classes and the one function.
class NodeList
{
public:
NodeList();
~NodeList();
//this should delete the whole list
void delList(NodeList * head);
private:
//head
NodeList * head;
};
//this is the nodestructkindathing
class Node
{
public:
Node();
~Node();
private:
//next pointer
Node * next;
int data;
};
void NodeList::delList(NodeList * head)
{
if (!head)
return;
delList(head->next);
delete head;
}
NOTE: I changed delList and Node * head in the class to become NodeList * head and now I only recieve one error.
error: ‘class NodeList’ has no member named ‘next’
As suggested by Some programmer dude, make NodeList a friend of Node. When class A declares class B to be a friend, B can see and interact with the private members of A. Note that the reverse is not true. friendship is one way. A cannot see the private members of B unless B declares A to be a friend.
This one change will solve all of the problems asked in the question.
The rest of this code dump is to make writing a linked list a little easier for you. Linked lists are best considered a rite of passage for programmers. You'll find you rarely use them in real life programming, but they serve as a notorious weeder of CS students. Practically no one gets them right the first time or two. They require a moderate amount of care and attention to book keeping. Pen and paper step-by-step drawings of the list and the interactions you wish to perform on the list are highly recommended to help visualize and debug a linked list.
You may also find delving into pointers to pointers extremely helpful. For example, see the Alternative Using Pointer To Pointer section of this linked answer.
Comments embedded where needed.
#include <iostream>
class Node
{
friend class NodeList; // NodeList, and no one else, can now see the private
// members of Node
public:
// Node must be given a value and it not given a next, it's automatically NULL
// this makes it almost impossible to not point link at something useful,
// eliminating the most common of the trivial linked list bugs
Node(int value, Node * link = nullptr);
~Node(); //if it doesn't do anything. Get rid of it. See the Rule of Zero
private:
//next pointer
Node * next;
int data;
};
class NodeList
{
public:
NodeList();
~NodeList();
//this should delete the whole list
void delList(Node * head);
private:
//head
Node * head;
};
Node::Node(int value, Node * link) : next(link), data(value)
{
// test code
std::cout << "Node data = " << data << " next = " << next << '\n';
}
Node::~Node()
{
// test code
std::cout << "~Node data = " << data << '\n';
}
NodeList::NodeList()
{
// test code to give delList something to delete
head = new Node(1,new Node(2,new Node(3)));
}
NodeList::~NodeList()
{
delList(head);
}
//this is the nodestructkindathing
void NodeList::delList(Node * head) // watch out! Parameter head shadows member head!
{
// Warning: This function is recursive and a potential stack-killer if given a
// long list. Prefer iteration here unless given a reason to do otherwise
// and guarantees on maximum list length
if (!head)
return;
delList(head->next);
delete head;
}
int main()
{
NodeList test;
}
Expected output:
Node data = 3 next = 0
Node data = 2 next = 0x2ec6cc0
Node data = 1 next = 0x2ec6ce0
~Node data = 3
~Node data = 2
~Node data = 1
A discussion of the Rules of Three, Five and Zero. Understanding these rules is a must if you want a stable linked list or to program non-trivial systems in C++.
Documentation on friend.
I want to create a generic linked list in C/C++ (without using templates of C++).
I have written following simple program and it works fine as of now -
typedef struct node
{
void *data;
node *next;
}node;
int main()
{
node *head = new node();
int *intdata = new int();
double *doubledata = new double();
char *str = "a";
*doubledata = 44.55;
*intdata = 10;
head->data = intdata;
node *node2 = new node();
node2->data = doubledata;
head->next = node2;
node *node3 = new node();
node3->data = str;
node3->next = NULL;
node2->next = node3;
node *temp = head;
if(temp != NULL)
{
cout<<*(int *)(temp->data)<<"\t";
temp = temp->next;
}
if(temp != NULL)
{
cout<<*(double *)(temp->data)<<"\t";
temp = temp->next;
}
if(temp != NULL)
{
cout<<*(char *)(temp->data)<<"\t";
temp = temp->next;
}
return 0;
}
My question is -
I need to know the data type of the data I am printing in the code above.
For example - first node is int so i wrote -
*(int *)(temp->data)
second is double and so on...
Instead, is there any generic way of simply displaying the data without worrying about the data type?
I know you can achieve this with templates, but what if I have to do this in C only ?
Thanks,
Kedar
The whole point of a generic list is that you can store anything in it. But you have to be realistic... You still need to know what you are putting in it. So if you are going to put mixed types in the list, then you should look at using a Variant pattern. That is, a type that provides multiple types. Here's a simple variant:
typedef struct Variant
{
enum VariantType
{
t_string,
t_int,
t_double
} type;
union VariantData
{
char* strVal;
int intVal;
double doubleVal;
} data;
} Variant;
You can then tell yourself "I'm storing pointers to Variants in my void* list. This is how you would do it in C. I assume when you say "C/C++" you mean that you're trying to write C code but are using a C++ compiler. Don't forget that C and C++ are two different languages that have some overlap. Try not to put them together in one word as if they're one language.
In C, the only way to achieve generics is using a void*, as you are already doing. Unfortunately, this means that there is no easy way to retrieve the type of an element of your linked list. You simply need to know them.
The way of interpreting data in memory is completely different for different data type.
Say a 32 bit memory block has some data. It will show different values when you typecast it as int or float as both are stored with different protocols. When saving some data in memory pointed by variable of type void*, it does not know how to interpret the data in its memory block. So you need to typecast it to specify the type in which you want to read the data.
This is a little bit like sticking all the cutlery in a drawer, but instead of putting knifes in one slot, forks in another slot, and spoons in a third slot, and teaspoons in the little slot in the middle, we just stick them all in wherever they happen to land when chucking them in, and then wondering why when you just stick your hand in and pick something up, you can't know what you are going to get.
The WHOLE POINT of C++ is that it allows you to declare templates and classes that "do things with arbitrary content". Since the above code uses new, it won't compile as C. So there's no point in making it hold an non-descriptive pointer (or even storing the data as a pointer in the first place).
template<typename T> struct node
{
T data;
node<T> *next;
node() : next(0) {};
};
Unfortunately, it still gets messier if you want to store a set of data that is different types within the same list. If you want to do that, you will need something in the node itself that indicates what it is you have stored.
I have done that in lists a few times since I started working (and probably a couple of times before I got a job) with computers in 1985. Many more times, I've done some sort of "I'll store arbitrary data" in a something like a std::map, where a name is connected to some "content". Every time I've used this sort of feature, it's because I'm writing something similar to a programming language (e.g. a configuration script, Basic interpreter, LisP interpreter, etc), using it to store "variables" that can have different types (int, double, string) or similar. I have seen similar things in other places, such as OpenGL has some places where the data returned is different types depending on what you ask for, and the internal storage has to "know" what the type is.
But 99% of all linked lists, binary trees, hash-tables, etc, that I have worked on contain one thing and one thing only. Storing "arbitrary" things in a single list is usually not that useful.
The answer below is targeting at C++ and not C. C++ allows for what you want, just not in the way that you want to do it. The way I would implement your problem would be using the built-in functionality of the virtual keyword.
Here's a stand-alone code sample that prints out different values no matter the actual derived type:
#include <iostream>
#include <list>
class Base
{
public:
virtual void Print() = 0;
};
class Derived1 : public Base
{
public:
virtual void Print()
{
std::cout << 1 << std::endl; // Integer
}
};
class Derived2 : public Base
{
public:
virtual void Print()
{
std::cout << 2.345 << std::endl; // Double
}
};
class Derived3 : public Base
{
public:
virtual void Print()
{
std::cout << "String" << std::endl; // String
}
};
int main(void)
{
// Make a "generic list" by storing pointers to a base interface
std::list<Base*> GenericList;
GenericList.push_back(new Derived1());
GenericList.push_back(new Derived2());
GenericList.push_back(new Derived3());
std::list<Base*>::iterator Iter = GenericList.begin();
while(Iter != GenericList.end())
{
(*Iter)->Print();
++Iter;
}
// Don't forget to delete the pointers allocated with new above. Omitted in example
return 0;
}
Also notice that this way you don't need to implement your own linked list. The standard list works just fine here. However, if you still want to use your own list, instead of storing a void *data;, store a Base *data;. Of course, this could be templated, but then you'd just end up with the standard again.
Read up on polymorphism to learn more.
Here is the header file
class sv1{
private:
struct Node{
string title;
Node* next;
};
public:
void InsertAfter(Node **head, string title);
void getMetadata(string t);
void q_folder(string t_q);
This is how the cc file will be
void sv1::getMetadata(string t)
{
Node *head=NULL;
title=t;
q_folder(title);
}
void sv1::q-folder(string t_q)
{
InsertAfter(&head,t_q);
}
void sv1::insertAfter(Node **head,string title)
{
if (head==NULL)
{
Node* temp=NULL;
temp=new Node;
temp->title=title;
*head=temp;
}
else{
Node *temp= new Node;
temp= new Node;
temp->title=title;
temp->next=(*head)->next;
(*head)->=temp;
}
}
The error says that the head is not declared in the function q_folder. What causes that and how do I solve it?
In your method, q-folder, you call insertAfter with "&head". The only way head could be recognizable in any class method is if it were
Local
Parameter
Class member (inherited or otherwise)
Global (however, consider this a no-no)
Seeing how it is none of the three, it doesn't know what you mean by "&head". Plus as hmjd correction mentioned, none of your declared methods are labeled as belonging to that class. You wrote them as if they were separate methods independent from any class. In order to indicate that they belong to class sv1, you need to add "sv1::" to the beginning of the method name.
I think you are pursuing a wrong pattern. Why have you defined Node struct inside private section of the class !? The usual pattern is that you have to separate classes for Node and LinkedList itself. Please create another class which encapsulate your node. Also you can implement it using templates to support different data types.
Also head is an internal variable. You shouldn't accept it as a function argument. This is not object oriented because your linked list (if it works) is not consistent and all defining variables are open to alter. You need you make head private for a LinkedList. Here you can find some examples :
Simple C/C++ Linked List
How to create Linked list using C/C++
Basically I am creating a base class that will be used for classes stored as a linked list, which are traversed and deleted as dictated by a virtual update() function which returns a bool.
I am wondering if this is the most efficient case (I like the fact that it can be a singley linked list in particular):
class Traversable
{
public:
Traversable();
virtual ~Traversable();
void traverse(Traversable** prevNext);
virtual bool update()=0;
protected:
private:
Traversable* next;
};
void Traversable::traverse(Traversable** prevNext)
{
if (!update()) /// Virtual function that returns a death flag
{ /// Death
if (next)
{
Traversable* localNext = next;
delete this;
localNext->traverse(prevNext);
}
else
{
*prevNext = NULL;
delete this;
}
}
else
{ /// This node stays alive, for now
*prevNext = this;
if (next)
{
next->traverse(&next);
}
}
}
Note the linked list is NULL terminated.
I think the careful lack of an assigment operation to a local variable after the next traverse function is called will secure usage of this function using tail calls. Can anyone spot anything I have done wrong, or perhaps suggest a slightly less convoluted approach :p
You're deliberately obfuscating the code in order to "tempt" the compiler into creating a specific result; whether this happens or not is quite probably more dependent on the compiler used, the optimization flags in effect, or even the code compiled that's using the above. The following is more compact code:
void Traversable::traverse(Traversable** prevNext)
{
bool doUpdate = update();
*prevNext = doUpdate ? this : next ? *prevNext : NULL;
Traversable **argNext = doUpdate ? &next : prevNext;
Traversable *localNext = next;
do_the_traversal_action(); // not spec'ed ...
if (!doUpdate)
delete this;
if (localNext)
localNext->traverse(argNext);
}
and still ends the function with a single tail return point. The only reason this uses conditionals is because you're changing prevNext in there.
Edit: what I'm trying to say is that no matter how you code it, in the end it's up to the compiler to decide whether it wants to tail-optimize the function or not. For modern optimizing compilers, there's often switches (-fconserve-stack or -foptimize-sibling-calls in GCC) that have a more immediate effect on this more than the sourcecode itself.
Edit 2: yes if course it's possible to write this function non-recursively; all it is, in the end, is a visitor type pattern. So the actual activity ends up being something like:
static void Traversable::traverse(Traversable *start)
{
Traversable *cur, *next;
for (cur = start; cur; cur = next) {
next = cur->next;
cur->do_the_traversal_action(); // not spec'ed ...
if (cur->update())
continue; // not supposed to remove this
if (next)
next->prevNext = cur->prevNext; // remove cur from list
delete cur;
}
}
Though, when you code it like that, the next obvious question is why one would not implement simple iterator types for Traversable and use std::remove_copy_if() for the visit-and-remove-on-condition task. Or use an STL list to start with.