How to create a linked list class?

Ok, so I want to create a class(MaterialList) that takes in an object from another class(Item), and adds it to a list. Then I want to be able to search through the list based on a given parameter.Ex:

Justin(name:"Justin",age:24,sex:male), Brittany(name:"Brittany",age:32, sex: female), Mikal(name:"Mikal",age:24,sex:male)....

Add to list:
list -> (Justin,Brittany,Mikal)

Then I want to be able to search and find all the names that is 24.
output: Justin and Mikal...

How do I do this in c++?

Here are my attempts, what am I missing here? Also, I still have to add in the part where you search through the list, but right now, I'm lost.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include<iostream> 
#include <list>
using namespace std; 

class Item{

//Access specifer
private:
string item;
int meshNum;
int mNum;

//constructor 
public:
Item( string item,int mNum, int meshNum  ){
    this->item=item;
    this-> mNum= mNum;
    this-> meshNum= meshNum;
    
}

//Memeber functions
public: 
string getItem(){
    return this->item;
}
void setItem(string item){
    this->item = item;
}
int getMeshNum(){
    return this->meshNum;
}
void setMeshNum(int meshNum){
    this->meshNum= meshNum;
}

int getMNum(){
    return this->mNum;
}
void setMNum(int mNum){
    this-> mNum= mNum;
}

};
//____________________________________________

 class materialList{
// Access specifer
private: 
list <Item> items;
 
 //constructor 
 public:
 materialList(){
     this->items = new list<Item>;
}

 // Memeber fucntions
 public:
 void add(Item item){
     items.push_back(item);
}
//print my list
 list<Item> Print(){
     cout<<"Working";
    for (list<Item>::iterator i=items.begin(); i!=items.end(); i++)
         cout << *i << " "; 
      
    cout << endl; 
}
};



 int main(){
     Item test= Item("door",34,50);
     itemList = materialList(list<Item> test);
     materialList.add(test);
     materialList.Print();

 }

Last edited on
first, a small thing, but it helps: stop naming stuff the same and you won't need a bajillion cluttery this pointers.

void setMNum(int mNum_in)
{
this-> mNum= mNum_in;
}

next, are you trying to make a linked list yourself, or use <list> container (which does all the work for you)? It looks like a weird mashup of these ideas --- you either roll your own (for study purposes) or use the built in one (what you would do if not studying how to roll your own) ?

to roll your own, you need simply to know that a class can have a pointer to its own type inside it.

eg
struct alist
{
alist * next;
int data;
//whatever else
}

Last edited on
I want to use a built in function <list>. No need to reinvent the wheel here.
ok.
you do not need 'new' here at all. That is for pointers and doing it yourself.
so your constructor is not necessary.

this works. I had to make several small changes, compare it to yours to see what I did.
As best as I remember it..
- you tried to use the class without objects in main (you need variables: a class is a TYPE and you can't just call methods, you need a variable of the TYPE then call methods on THAT)
- you had the new stuff, which was not correct
- you had print returning something, which it should not
- cleaned up the giant for loop
- your print was trying to print a class that did not overload << ... you can either overload << yourself or do as I did and print from a getter.
- your print is probably nothing like what you wanted now, but it should be an example of what you need to do.
- may be one or two other minor syntax issues

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include<iostream> 
#include <list>
using namespace std; 

class Item{

//Access specifer
public: //todo, private with get/set 
string item;
int meshNum;
int mNum;

//constructor 
public:
Item( string item,int mNum, int meshNum  ){
    this->item=item;
    this-> mNum= mNum;
    this-> meshNum= meshNum;
    
}

//Memeber functions
public: 
string getItem(){
    return item;
}
void setItem(string item){
    this->item = item;
}
int getMeshNum(){
    return this->meshNum;
}
void setMeshNum(int meshNum){
    this->meshNum= meshNum;
}

int getMNum(){
    return this->mNum;
}
void setMNum(int mNum){
    this-> mNum= mNum;
}

};
//____________________________________________

 class materialList{
// Access specifer
private: 
list <Item> items;
 
 //constructor 
 public:
/* materialList(){
     this->items = new list<Item>;
} */

 // Memeber fucntions
 public:
 void add(Item &item)
 {
     items.push_back(item);
 }
//print my list
void Print()
 {
     cout<<"Working ";
    for (auto &i : items)
         cout << i.getItem() << " "; 
      
    cout << endl; 
	cout<<"Print done  ";
}
};



 int main(){
     Item test= Item("door",34,50);
     //itemList = 
	 materialList ml; //(list<Item> test);
     ml.add(test);
     ml.Print();

 }


Last edited on
Thanks, but how would I get able to print out all the items on the list that has a given mNum value inserted by the user? Could you help me on this? I've been trying to figure this out. List are so much easier in java and python ugh.
part of the difficulty is that you are making a wrapper for list instead of just using it, adding a layer of aggravation. There is no need (so far? ) for the materialList class, just make a list of your other object and use it directly.

you can print whichever items in similar ways.

cout << i.getMeshNum()
etc. doing it this way, you have to print them one item at a time using getter functions.
you can also overload the << operator so you can just say
cout << i << endl; //i's stream operator would format the data somehow.
I am not a huge fan of the << overload because its going to have a fixed format whereas you can roll out a cout statement to print the parts you want in the order you want for the purpose you have at the current moment, but if you know you only want one specific format for it all its fine, or if you want to make it virtual or something there are options.
Last edited on
Using std::list, consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <list>
#include <iostream>
#include <algorithm>


enum class Sex {male = 0, female};

struct Item {
	std::string name;
	int age;
	Sex sex;

	Item(const std::string& nam, int age_, Sex sex_) : name(nam),age(age_), sex(sex_) {}
};

std::ostream& operator<<(std::ostream& os, const Item& item)
{
	static const char* s[] {"male", "female"};

	return os << item.name << "  " << item.age << "  " << s[(int)item.sex];
}

int main()
{
	std::list<Item> mylist;

	mylist.emplace_back("Justin", 24, Sex::male);
	mylist.emplace_back("Brittany", 32, Sex::female);
	mylist.emplace_back("Mikal", 24, Sex::male);

	for (const auto& l : mylist)
		std::cout << l << std::endl;

	std::cout << std::endl;

	// Search for and display age equal 24
	for (auto it = mylist.begin(); (it = std::find_if(it, mylist.end(), [](auto i) {return i.age == 24; })) != mylist.end(); ++it)
		std::cout << *it << std::endl;
}

Last edited on
That latter loop could look "simpler" as:
1
2
3
4
5
for ( const auto& l : mylist ) {
  if ( l.age == 24 ) {
    std::cout << l << '\n';
  }
}

Either way we do iterate over every element in the list.


One can still have alias for the typename:
1
2
using MaterialList = std::list<Item>;
MaterialList mylist;

... but it does not give any benefit in this short program.
Topic archived. No new replies allowed.