C++ Changing Struct to Class [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am doing linked list exercises and currently understand how to write a link list in struct format. However I would like to change my code to make linked list a class and have the print, sort, add, delete, functions as members of the class. Please give me ideas on how this can be done.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstddef>
using namespace std;
struct mylist {
int payload;
struct mylist * link;
};
void addlink(struct mylist *, int);
struct mylist * droplink(struct mylist *);
void printmylist(struct mylist *);
void sortmylist(struct mylist *);
int main() {
struct mylist head;
struct mylist *lptr;
head.payload = 15;
head.link = 0;
lptr = &head;
printmylist(lptr);
addlink(lptr, 21);
printmylist(lptr);
addlink(lptr, -5);
printmylist(lptr);
addlink(lptr, 90);
printmylist(lptr);
lptr = droplink(lptr);
printmylist(lptr);
sortmylist(lptr);
printmylist(lptr);
return 0;
}
void addlink(struct mylist *lp, int val) {
struct mylist *temp;
struct mylist *newlink;
//run out to end of chain
temp = lp;
do {
if (temp->link != 0)
temp = temp->link;
} while (temp->link != 0);
newlink = (struct mylist *) malloc(sizeof(struct mylist));
newlink->payload = val;
newlink->link = 0;
temp->link = newlink;
return;
}
struct mylist * droplink(struct mylist *lp) {
cout << "Releasing front value of " << lp->payload << endl;
return lp->link;
}
void printmylist(struct mylist *lp) {
struct mylist *temp;
temp = lp;
while (temp->link != 0) {
cout << temp->payload << " then ";//if there is just one link, loop never runs
if (temp->link != 0)
temp = temp->link;
}
cout << temp->payload; //gets the last link's value
cout << endl;
return;
}
void sortmylist(struct mylist *lp) {
struct mylist *temp;
struct mylist *temp2;
int linkcount = 1;
int temppayload;
temp = lp;
while (temp->link != 0) {
if (temp->link != 0) {
++linkcount;
temp = temp->link;
}
}
cout << linkcount << " links " << endl;
temp = lp;
for (int ct2 = 1; ct2 < linkcount; ++ct2) {
temp = lp;
for (int ct = 1; ct < linkcount; ++ct) {
if (temp->link != 0)
temp2 = temp->link;
if (temp->payload > temp2->payload) {
temppayload = temp->payload;
temp->payload = temp2->payload;
temp2->payload = temppayload;
}
if (temp2->link != 0)
temp = temp2;
}
}
}

The only real difference between a struct and a class in C++ is that by default all members of a class are private, and all members of a struct are public.
I assume what you're really asking is how to make your linked list methods members of your struct / class. This is very easy.
All of your existing methods accept a struct mylist* as the first parameter. In C++, this is provided automatically by the compiler, as a hidden parameter called this. You can refer to this explicitly, but it is also accessible implicitly.
So where in C you might have:
lp->payload = 0;
In a C++ class member function, you could have:
this->payload = 0;
Or more commonly:
payload = 0;
So broadly speaking, the steps required to "c++ify" your C code are:
Move the declarations of the methods into the body of the struct
Remove the struct mylist * argument from each method
Remove the references to lp in each method
Call the member functions by dereferencing an instance of the struct (e.g. lptr->addlink(-5);)

As a rule, you can change every struct that is passed to a linked list function from:
struct Node {
int payload;
struct Node *link;
};
...
void addlink(struct Node *lp, int val) {
...
}
to this:
class Node {
public:
Node() : _link(0), _payload(0) { } // initialize members on new empty node
Node(int val) : _link(0), _payload(val) { } // pass a new value directly
~Node() {
// call a function to clear everything pointed to from _link
}
void addlink(int val) {
Node *temp = this;
do {
if (temp->link() != 0)
temp = temp->link();
} while (temp->link() != 0);
Node *newlink = new Node(val); // this will do what the next 2 lines do
//Node *newlink = new Node; <- you can also create a Node this way and then assign the payload
//newlink->setPayload(val);
// newlink->link = 0; <-- not needed 'new Node' has already initialized it
temp->setLink(newlink);
}
// provide access to the data (get/set)
int payload() { return _payload; }
void setPayload(int n) { _payload = n; }
Node *link() { return _link; }
void setLink(Node *p) { _link = p; }
// data members
private:
int _payload;
Node *_link;
};
This fragment gives you the idea. Now you can add the rest :)
The best of course, is to place the code within the functions in a .cpp file and leave the definition of the class in the header:
class Node {
public:
Node();
Node(int val); // pass a new value directly
~Node();
void addlink(int val);
// provide access to the data (get/set)
// you can leave thse one liners in the header, they'll most likely be inlined
int payload() { return _payload; }
void setPayload(int n) { _payload = n; }
Node *link() { return _link; }
void setLink(Node *p) { _link = p; }
// data members
private:
int _payload;
Node *_link;
};
The bodies of the functions in the cpp:
Node::Node() : _link(0), _payload(0)
{
}
Node::Node(int val) : _link(0), _payload(val)
{
}
......
Hope this helps.

Related

Empty a linked-list object [duplicate]

This question already has an answer here:
Deleting the whole Linked List
(1 answer)
Closed 5 months ago.
I have my linked list code:
#include <string>
#include <iostream>
using namespace std;
class Node
{
public:
string name;
int age;
Node *next;
Node(string name, int age)
{
this->name = name;
this->age = age;
this->next = nullptr;
}
};
class List
{
private:
Node *head;
int size;
public:
List()
{
this->head = nullptr;
this->size = 0;
}
void insert(string name, int age)
{
Node *nodenew = new Node(name, age);
nodenew->next = nullptr;
if (this->head == nullptr)
{
this->head = nodenew;
}
else
{
Node *auxi = this->head;
while (auxi->next != nullptr)
{
auxi = auxi->next;
}
auxi->next = nodenew;
}
this->size = this->size + 1;
}
void print()
{
if (this->head == nullptr)
{
cout << "List is empty"<<endl;
}
Node *auxi = this->head;
cout<<to_string(this->size)+" users in the linked list"<<endl;
while (auxi != nullptr)
{
cout << auxi->name << ", " << auxi->age << endl;
auxi = auxi->next;
}
}
};
int main()
{
List linkedList;
linkedList.insert("David", 56);
linkedList.insert("Susan", 25);
linkedList.insert("Kim", 41);
linkedList.insert("Charles", 23);
linkedList.insert("Bob", 20);
linkedList.insert("James", 75);
linkedList.insert("Carl", 36);
linkedList.insert("Andy", 78);
linkedList.print();
return 0;
}
As you can see I did insert method, print method. And now want I want is to delete all nodes in the linkedList object, so I would like to know if there is some way to make for example something like linkedList = nullptr or something similar to delete all data in my linked list.
I tried to make that in the main method:
linkedList = nullptr;
But my compiler shows me this error:
no operator "=" matches these operands
I hope you can help me, thanks.
linkedList = nullptr; won't work, since it makes no sense. linkedList isn't a pointer. It has a pointer inside of it, but it's not itself a pointer. Besides, if that did work, it wouldn't delete the nodes, so it would be a memory leak.
You should create a function empty() (or more usually called clear()) in your List class. Make it so it deletes all the nodes, then sets head to nullptr and size to 0. Then in main(), you can call linkedList.empty(); (or linkedList.clear();)

What does this strange number mean in the output? Is this some memory Location? [duplicate]

This question already has answers here:
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 1 year ago.
The node Class is as follow:
class node
{
public:
int data; //the datum
node *next; //a pointer pointing to node data type
};
The PrintList Function is as follow:
void PrintList(node *n)
{ while (n != NULL)
{
cout << n->data << endl;
n = n->next;
}
}
If I try running it I get all three values (1,2,3) but I get an additional number as well which I'm unable to figure out what it represents, Can someone throw light on the same?
int main()
{
node first, second, third;
node *head = &first;
node *tail = &third;
first.data = 1;
first.next = &second;
second.data = 2;
second.next = &third;
third.data = 3;
PrintList(head);
}
I Know it can be fixed with
third.next = NULL;
But I am just curious what does this number represents in output, If I omit the above line
1
2
3
1963060099
As described in the comment by prapin, third.next is not initialized.
C++ has a zero-overhead rule.
Automatically initializing a variable would violate this rule as the value might be initialized (a second time) later on or never even be used.
The value of third.next is just the data that happened to live in the same memory location as third.next does now.
For this reason, it's recommended to always initialize your variables yourself.
It is better to initialize variables & it is better to use nullptr. Like that (See 1-3):
#include <iostream>
class node
{
public:
int data = 0; // 1
node* next = nullptr; // 2
};
void PrintList(node* n)
{
while (n != nullptr) // 3
{
std::cout << n->data << std::endl;
n = n->next;
}
}
int main()
{
node first, second, third;
node* head = &first;
node* tail = &third;
first.data = 1;
first.next = &second;
second.data = 2;
second.next = &third;
third.data = 3;
// third.next points to where?
PrintList(head);
}
Additional note:
I would prefer to use the STL container std::list:
#include <list>
#include <iostream>
std::list<int> int_list;
void PrintList()
{
for (auto i : int_list)
std::cout << i << std::endl;
}
int main()
{
int_list.push_back(1);
int_list.push_back(2);
int_list.push_back(3);
PrintList();
}
Or in case of list of node objects:
#include <list>
#include <iostream>
class node
{
public:
node(int data) : m_data{ data } {};
int m_data = 0;
// and maybe extra data-members
};
std::list<node> node_list;
void PrintList()
{
for (auto i : node_list)
std::cout << i.m_data << std::endl;
}
int main()
{
node_list.push_back(node(1));
node_list.push_back(node(2));
node_list.push_back(node(3));
PrintList();
}

How can I have a linked-list using class?

I'm trying to write a linked-list using class and I want it to have a specific format.
For example if I have three data called p1,p2 and p3 and a linked-list called list; I want to put them in order like blow.
list.insert(p1).insert(p2).insert(p3);
I tried to return the object, but didn't work.
Here's my code.
#include<iostream>
using namespace std;
class linked_list {
public:
int *head;
linked_list();
~linked_list();
linked_list insert(int data);
};
linked_list::linked_list()
{
head = NULL;
}
linked_list::~linked_list()
{
int *temp;
int *de;
for (temp = head;temp != NULL;) {
de = temp->next;
delete temp;
temp = de;
}
delete temp;
//delete de;
}
linked_list linked_list::insert(int data)
{
int *temp;
temp = new int;
*temp = data;
temp->next = NULL;
if (head == NULL) {
head = temp;
}
else {
int* node = head;
while (node->next != NULL) {
node = node->next;
}
node->next = temp;
// delete node;
}
//delete temp;
return *this;
}
int main(){
linked_list l1;
int p1,p2,p3;
l1.insert(p1).insert(p2).insert(p3);
return 0;}
#Jarod42 got your answer, despite all the buggy things around, what you want is something like this.
The function you want to chain must return a reference to your current object instance.
Here is a Foo class that change its _data member and chain multiple time.
#include <iostream>
class Foo
{
private:
int _data;
public:
Foo(int data) : _data(data) {}
~Foo()
{
}
// change the value of data then return a reference to the current Foo instance
Foo &changeData(int a)
{
_data = a;
return *this;
}
void printData()
{
std::cout << _data << std::endl;
}
};
int main()
{
Foo f(1);
f.changeData(2).changeData(3);
f.printData();
}
Note that I'm returning Foo& from the function I'm chaining, that's the little trick that is missing from yours.
Hope it helped you :)

Figuring out Insert function parameter for linked list?

My teacher gave the class for a driver to complete a program, and I'm unsure how to code the insert function because of it.
The line giving me trouble:
you.Insert(me,0);
you is for the default constructor and me is for an explicit value constructor, so this line is supposed create a node in you with the contents of me.
I'm lost understanding how to write the parameter to access me for my insert function
void WRD::Insert( ?, int new_data)
I'll include the explicit constructor I have, any insight understanding this mentally will help. (included example of what insert should look like or do based on an example I was given.)
WRD::WRD(const string & s)
{
cout<<"one called\n";
front = 0;
for(unsigned i=0; i<s.length(); i++)
{
AddChar(s[i]);
}
}
class node
{
public:
char symbol;
node * next;
};
v
oid Insert(node * &ptr, int new_data)
{
node *new_ptr = new node;
new_ptr -> data = new_data;
new_ptr -> next = 0; //always initialize a pointer
if (Empty(ptr))
{
ptr = new_ptr;
}
else if (new_ptr->data <= ptr->data)
{
new_ptr->next = ptr;
ptr = new_ptr;
}
else
{
node *fwd_ptr=ptr, *pre_ptr=ptr;
while(fwd_ptr!=0 && (fwd_ptr->data < new_ptr->data))
{
pre_ptr = fwd_ptr;
fwd_ptr = fwd_ptr->next;
}
if (fwd_ptr == 0)
{
pre_ptr->next = new_ptr;
}
else
{
new_ptr->next = fwd_ptr;
pre_ptr->next = new_ptr;
}
}
}
Like this I think (assuming I've understood you right)
void WRD::Insert(const WRD& w, int new_data)
It might help to show more of your driver program, in particular how you and me are declared.

C++ Singly Linked List Find Nodes value x spaces from beginning

float get(int x) {
if(x == 0) {return head->x;}
else {
Node *current = head;
for(int a=0; a<x; a++) {
current = current->next;
}
return current->x;
}
}
This is my code, but when I run it with a test case, it says "Lab3.exe has stopped working". I'm still really new to C++ and our teacher hasn't been helpful in the slightest, can anyone give me advice on my implementation?
EDIT:
Here's the test case...
#include <iostream>
#include <string>
using namespace std;
// including _my copy_ of SLList
#include "./SLList.h"
using namespace ods;
template <class FloatList>
bool listTest(){
FloatList L;
L.add(0, 3.14);
L.remove(0);
L.add(0, 1.62);
L.add(1, 2.23);
L.set(1, 2.72);
/*float x = L.get(1);*/
return ( 2.72f == L.get(1) and 2 == L.size() );
}
int main() {
if ( listTest<SLList<float> >() )
cout << "SLList passes basic list interface test" << endl;
else
cout << "SLList FAILS basic list interface test" << endl;
}
And here's how the SLL is set up:
template<class T>
class SLList {
T null;
protected:
class Node {
public:
T x;
Node *next;
Node(T x0) {
x = 0;
next = NULL;
}
};
Node *head;
Node *tail;
int n;
public:
SLList() {
null = (T)NULL;
n = 0;
head = tail = NULL;
}
virtual ~SLList() {
Node *u = head;
while (u != NULL) {
Node *w = u;
u = u->next;
delete w;
}
}