New to programming , but when I try to create this link list I receive an error 'no matching function for call to 'meetings::meetings()' Been through it a few times and I'm just not seeing what it causing the issue.
class meetings{
public:
void duplicatetest (string,memberlist *&head);
void menufn(memberlist *&head);
void meetinginfo( memberlist *&head,string);
string timestamp ( memberlist *&head,string);
memberlist *&head;
string UID;
string timestp;
meetings *timest;
meetings *link;
int meetnum;
string dt;
};
void meetings::meetinginfo(memberlist *&head, string dt ){
string meetingNum;
memberlist *currptr;
meetings *meetptr , *nnmeet ,*meetcurr, *meethead;
meethead= NULL;
if (currptr->meetnum == 0 ) {
meethead = new meetings; // <<< Error appears here!
meetingNum = currptr->UID;
meethead->UID = meetingNum;
meethead->timestp = dt;
meetcurr=meethead;
system ("pause");
}
else {
nnmeet = new meetings;
meetcurr->link= nnmeet;
nnmeet->UID=currptr->UID;
nnmeet->timestp = dt;
}
cout << "Meeting number : ";
menufn(head);
}
using namespace std;
#include "memberlist.h"
#include "meeting.h"
int main(){
system("color f0");
memberlist *member,entermember;
meetings menu, *meet;
entermember.createlinklist(member);
menu.menufn(member);
system("pause");
return 0;
}//End of main
This is the other class I refer to from the meetings class
class memberlist {
public:
void createlinklist (memberlist *&head);
void displaylist (memberlist *&head);
memberlist *link;
string name[2];
string UID;
int meetnum;
};
void memberlist::createlinklist (memberlist *&head)
{
ifstream fin;
memberlist *currptr , *nnptr;
head = NULL;
fin.open ("members.txt");
while (fin)
{
if(head==NULL)
{
head = new memberlist;
fin>>head->UID >> head->name[0] >> head->name[1];
head->meetnum = 0;
currptr = head;
}
nnptr = new memberlist;
currptr->link = nnptr;
fin>>nnptr->UID >> nnptr->name[0] >> nnptr->name[1];
nnptr->meetnum = 0;
currptr = nnptr;
}
currptr->link = NULL;
currptr = NULL;
displaylist(head);
}
void memberlist::displaylist (memberlist *&head)
{
//memberlist *meetptr;
cout << " Student information " << endl;
memberlist *currptr;
currptr = head;
//meetptr = meethead;
while (currptr->link!= NULL)
{
cout << setw(10) << left << currptr->UID << " " << currptr->name[0] <<" " <<
currptr->name[1] <<endl;
currptr= currptr->link;
}
}
The problem is that data member head is defined as a reference.
memberlist *&head;
The compiler is unbale to generate the default constructor becuase it does not know how to initialize the reference. You have to define the constructor yourself.
According to the C++ Standard
A defaulted default constructor for class X is defined as deleted if:
— any non-static data member with no brace-or-equal-initializer is of
reference type,
Also take into account that referebces can be initialized only in the ctor initializer. For example
meetings::meetings( memberlist * &ptr ) : head( ptr )
{
// possible some additional code
}
Or as it is said in the quote I cited in the class definition using brace-or-equal-initializer.
Related
I have a while loop as part of a class.
#include <iostream>
#include <iomanip>
#include <fstream>
struct familyFinance{ //add 3rd member familyFinance;
int acctNos; float Balance; struct familyFinance *nextNodePointer;
struct familyFinance *dynMemory;
};
using namespace std;
class myFinanceClass {
private:
string fileName="";
familyFinance *ptrHead = nullptr;
public:
void setFileName(string){ fileName="Lab5Data.txt";}
void readFileAndBuildLinkedList(){
ifstream Lab3DataFileHandle;
familyFinance *ptrHead=nullptr;
//familyFinance *dynFinancePtr=nullptr;
familyFinance *tempPtr;
tempPtr=ptrHead;
Lab3DataFileHandle.open(fileName.c_str());
while (!Lab3DataFileHandle.eof( )) {
familyFinance *dynFinancePtr= new familyFinance;
Lab3DataFileHandle >> dynFinancePtr -> acctNos;
Lab3DataFileHandle >> dynFinancePtr -> Balance;
// familyFinance *nextNodePointer = nullptr;
if (ptrHead == nullptr) {
ptrHead = dynFinancePtr;
}
else {
tempPtr = ptrHead;
while (tempPtr -> nextNodePointer != nullptr )
tempPtr = tempPtr->nextNodePointer;
tempPtr->nextNodePointer = dynFinancePtr;
}
}
Lab3DataFileHandle.close();
}
void spitThemOut(){
familyFinance *tempNodePtr;
tempNodePtr = ptrHead;
Here is the While Loop
while (tempNodePtr) {
cout << "Acct, Balance: " << setw(3)
<<ptrHead->acctNos << " " <<ptrHead->Balance << endl;
tempNodePtr = tempNodePtr->nextNodePointer;
}
}
When I call the function from class in main I know it can read the function it just won't execute the while loop. What do I need to change to execute the while loop. It would be much apprenticed if you showed an example in your answer. Thank you for your time.
If the while loop is in the method and defined in that class, that won't execute, cause it's not allowed by the language. Methods defined within the class are not allowed to have any loops. There are a few more restrictions that apply for methods defined within the class. Such a case can be solved by declaring the method in the class but defining it outside the class as shown below
class myFinanceClass {
... // all the code before spitThemOut()
void spitThemOut();
};
void myFinanceClass::spitThemOut() {
... // code to work
while (tempNodePtr) {
...
}
}
I have a class Employee with pointer variables tag and values of type char and a self reference pointer children. We also have another two integer variables "numAttributes" and "numChildren". "numChildren" specifies how may children can be added to the class. "numAttributes" is for future purpose. I have to allocate and deallocate memory. For this I'm trying to implement a copy constructor and a destructor. The problem I am facing is, I couldn't able to deep copy the whole class when it has the children var not NULL. I have tried using memcpy() and also the solution mentioned here. But I couldn't able to do it properly. When everything goes well it fails in destructor. What I have tried so far is:
#include<iostream>
#include<stdlib.h>
#include<string>
#include<map>
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
class Employee
{
public:
char* tag;
char* value;
int numAttributes;
int numChildren;
Employee* children;
Employee(const Employee &attr)
{
cout << "Copy constructor called" << endl;
numAttributes = attr.numAttributes;
numChildren = attr.numChildren;
tag = (char*)malloc(sizeof(char)*strlen(attr.tag) + 1);
value = (char*)malloc(sizeof(char)*strlen(attr.value) + 1);
strcpy(tag, attr.tag);
strcpy(value, attr.value);
if (attr.children == NULL)
children = NULL;
else
children = attr.children; // shallow copy happening. Have to do deep copy if it has children
}
Employee(){
cout << " constructor called" << endl;
tag = NULL;
value = NULL;
children = NULL;
numAttributes = 0;
numChildren = 0;
}
~Employee(){
cout << "Destructor called" << endl;
if (tag != NULL){
free(tag);
tag = NULL;
}
if (value != NULL){
free(value);
value = NULL;
}
if (children != NULL){
free(children);
children = NULL;
}
}
};
Employee createNode(const char* tag, const char* value, unsigned int numAttributes, unsigned int numChildren)
{
Employee retNode;
retNode.tag = (char*)malloc(sizeof(char)* (strlen(tag) + 1));
strcpy(retNode.tag, tag);
retNode.value = (char*)malloc(sizeof(char)* (strlen(value) + 1));
strcpy(retNode.value, value);
retNode.numAttributes = numAttributes;
retNode.numChildren = numChildren;
//use this block if we are not initializing the children in the createOffset() method
/*if (numChildren == 0){
retNode.children = NULL;
}
else{
retNode.children = (Employee*)malloc(sizeof(Employee)*numChildren);
}*/
return retNode;
}
Employee createOffset()
{
//Create and tag initial root node
Employee retNode = createNode("offset", "value", 0, 1);
retNode.children = (Employee*)malloc(sizeof(Employee)*retNode.numChildren);
retNode.children[0] = createNode("prnt", "0000", 0, 0);
return retNode; // Until here it is fine. This return calls the copy constructor first. As it has children the children must also be deep copied. Getting error here. Have to do deep copy the entire the class
}
Employee get(){
return createOffset();
}
int main(){
Employee node = get();
getchar();
return 0;
}
struct Employee {
std::string tag;
std::string value;
int numAttributes = 0;
std::vector<Employee> children;
};
no need to write a copy constructor or destructor, the C++ language makes one for you that does the right thing here.
This is known as the rule of 0.
Employee createNode(const char* tag, const char* value, unsigned int numAttributes, unsigned int numChildren)
{
return {tag, value, numAttributes, std::vector<Employee>(numChildren)};
}
also a lot shorter.
Employee createOffset()
{
//Create and tag initial root node
Employee retNode = createNode("offset", "value", 0, 1);
retNode.children[0] = createNode("prnt", "0000", 0, 0);
return retNode;
}
and done.
The following code is printing out 343. I don't understand why it isn't taking in currentDirectory by reference and updating what it's pointing to to a subdirectory of the root instance.
I would expect it to output 344.
#include <iostream>
using namespace std;
class Directory;
struct Node{
Node* prev;
Node* next;
Directory* data;
};
class Directory{
public:
int testValue;
Node* subDirectories;
void addSubdirectory(int testValue){
Directory* newDirectory = new Directory(testValue);
Node* elem = new Node;
elem->prev = NULL;
elem->data = newDirectory;
elem->next = NULL;
subDirectories = elem;
}
Directory(int x){
testValue = x;
}
};
void testFunction(Directory* x){
x = x->subDirectories->data;
cout << x->testValue;
}
int main(){
Directory* root = new Directory(3);
root->addSubdirectory(4);
Directory* currentDirectory = root;
cout << currentDirectory->testValue;
testFunction(currentDirectory);
cout << currentDirectory->testValue;
}
I've tried a simplified example that works fine:
#include <iostream>
using namespace std;
class Directory;
class Directory{
public:
int testValue;
Directory(int x){
testValue = x;
}
};
void testFunction(Directory* x){
x->testValue = 4;
cout << x->testValue;
}
int main(){
Directory* root = new Directory(3);
Directory* currentDirectory = root;
cout << currentDirectory->testValue;
testFunction(currentDirectory);
cout << currentDirectory->testValue;
}
This prints out 344 as expected. This one is passing it in by reference.
Your problem is that you are passing by value not by reference. The instance that is being passed to "testfunction()" is "currentDirectory" which is a pointer to object. So if you intend to pass by reference it should be like this:
void testFunction(Directory* &x){
x = x->subDirectories->data;
cout << x->testValue;
}
You are making a copy of type Directory* and passing it into testFunction as an argument. That copy, x, is not a reference to the pointer root.
This is probably what you want:
void testFunction(Directory* &x){
x = x->subDirectories->data;
cout << x->testValue;
}
Or if you prefer the double pointer route you would have:
void testFunction(Directory** x){
(*x) = (*x)->subDirectories->data;
cout << (*x)->testValue;
}
// the call turns into
testFunction(¤tDirectory)
Your simplified example works because you are not actually assigning to the variable that is passed-by-value, x:
void testFunction(Directory* x){
x->testValue = 4; // assigning pointed-to value, not pointer
cout << x->testValue;
}
Long story short, pointer-to-type is a type in and of itself too. Passing a pointer by reference takes the same changes as any other type.
Alternately, you could create an object of the class rather than a pointer. Note, this would require you to add a copy constructor (and, hopefully, a destructor, and overloaded operator=).
Directory root(3);
root.addSubdirectory(4);
//Assuming you overload operator=
Directory currentDirectory = root;
cout << currentDirectory.testValue;
testFunction(currentDirectory);
Where
void testFunction(Directory & x);
I was trying to build my own binary search tree. However , my tree is not getting built. Please see code below and help.
#include<iostream>
#include<string>
using namespace std;
class Binarytree
{
private:
struct node
{
int data;
node *left;
node *right;
};
node *root;
public:
Binarytree();
void insertdata(node*,int);
void deletedata();
void printdata(node*);
void userprint(char);
void getdata(int);
};
Binarytree::Binarytree()
{
root=NULL;
cout<<"Setting root as NULL"<<endl;
}
void Binarytree::insertdata(node* temp3,int temp)
{ cout << "in insert data"<<endl;
node Dummy=node();
Dummy.data=temp;
Dummy.left=NULL;
Dummy.right=NULL;
cout << "Data To be inserted is "<<temp <<endl;
if (temp3 == NULL)
{ cout<<"Found NULL ROOT"<<endl;
temp3=&Dummy;
cout << "Entered a Data in tree"<<endl;
cout<<"Data in root"<<root->data<<endl;
}
else if (temp3->data > temp)
{ cout<<"Making a Left Recursive Call"<<endl;
insertdata(temp3->left,temp);
}
else
{ cout<<"Making a right Recursive Call"<<endl;
insertdata(temp3->right,temp);
}
}
void Binarytree::getdata(int check)
{ cout <<"in getdata"<<endl;
cout << "before insertdata"<<endl;
insertdata(root,check);
}
void Binarytree::printdata(node* printrt)
{
if (printrt ==NULL)
cout << "Nothing to print";
else
{ cout << printrt->data << endl;
printdata(printrt->left);
printdata(printrt->right);
}
}
void Binarytree::userprint(char in)
{ node* data;
data=root;
if (in == 'Y' || in == 'y')
printdata(data);
}
void main()
{ Binarytree element=Binarytree();
int userdata,i=0;
bool check = true;
while(check)
{ cout <<"Please Enter your Data"<<endl;
cin >> userdata;
element.getdata(userdata);
cout<<"FUnction returned to main"<<endl;
i++;
if(i==5)
check=false;
}
element.userprint('Y');
}
The very first value is not getting inserted in root pointer. I know there are lots of code available for doing this but if i don't code it my own I feel my learning will be limited.
So please help in figuring error in this code.
Having really tried to compile and there might be other problems... but
change
void Binarytree::insertdata(node* temp3,int temp)
to
void Binarytree::insertdata(node* &temp3,int temp)
so that the node created inside insertdata really modifies the outside pointer.
and change
node Dummy=node();
Dummy.data=temp;
Dummy.left=NULL;
Dummy.right=NULL;
to
node *Dummy=new node();
Dummy->data=temp;
Dummy->left=NULL;
Dummy->right=NULL;
As I said there might be other problems... you should worry about deleting nodes and all that...
Alternative you could create nodes outside of insertdata() and keep the same signature.
Anyway, good luck
The root cause (if you'll pardon the pun) is the way you're adding things to the root of the tree. Your code creates a temporary variable called Dummy on the stack and then takes its address. That's the first mistake because that temporary variable gets destroyed when the function ends.
The second problem is that in order to change the value of a pointer that you pass to a function, you have to pass a pointer to a pointer. In other words, your member function that was insertdata(node *, int) must become insertdata(node **, int)if you want to actually change the passed pointer rather than just a local copy as your original code had done.
To illustrate that fact, try this code.
#include <iostream>
int Y = 99;
void makeitsix(int n) {
n = 6;
}
void pointToY(int *ptr) {
ptr = &Y;
}
int main()
{
int x = 5;
int *p = &x;
std::cout << "x = " << x << ", *p = " << *p << std::endl;
makeitsix(x);
pointToY(p);
std::cout << "x = " << x << ", *p = " << *p << std::endl;
return 0;
}
When makeitsix() gets called, it's only the local copy of n that is altered, and not the value of 5 that was originally passed in. Similarly, ptr in the pointToY() function is only altering a local copy of ptr and not p that was used to call the function from within main(). If it were not so, an invocation such as makeitsix(3) would lead to some very strange effects!
I took the liberty of changing things somewhat in your code to make it a little cleaner, including
giving the node structure its own constructor
creating an extractor for the Binarytree
removing the various diagnostic printout statements (for brevity)
making the tree printout look more like a tree with the root to the left and the branches extending rightward
made some member functions private
and a few other minor things. The complete working code is below:
#include<iostream>
#include<string>
class Binarytree
{
private:
struct node
{
node(int d=0) : data(d), left(NULL), right(NULL) {};
int data;
node *left;
node *right;
};
node *root;
void insertdata(node**,int);
std::ostream& printdata(std::ostream &out, node*, int depth=0);
public:
Binarytree() : root(NULL) {};
std::ostream &printTo(std::ostream &out);
void insert(int);
};
void Binarytree::insertdata(node** temp3,int temp)
{
node *Dummy=new node(temp);
if (*temp3 == NULL) {
*temp3=Dummy;
} else if ((*temp3)->data > temp) {
insertdata(&((*temp3)->left),temp);
} else {
insertdata(&((*temp3)->right),temp);
}
}
void Binarytree::insert(int check)
{
insertdata(&root,check);
}
std::ostream &Binarytree::printdata(std::ostream &out, node* printrt, int depth)
{
if (printrt != NULL)
{
printdata(out, printrt->left, depth+1);
for (int i = 0; i < depth; ++i)
out << '\t';
out << printrt->data << std::endl;
printdata(out, printrt->right, depth+1);
}
return out;
}
std::ostream &Binarytree::printTo(std::ostream &out)
{
return printdata(out, root);
}
std::ostream &operator<<(std::ostream &out, Binarytree &b)
{
return b.printTo(out);
}
int main()
{
Binarytree element;
int userdata,i=0;
bool check = true;
while(check)
{
std::cout << "Please Enter your Data" << std::endl;
std::cin >> userdata;
element.insert(userdata);
i++;
if(i==5)
check=false;
}
std::cout << "Tree:\n" << element << std::endl;
return 0;
}
I'm am fairly new to C++.
I have this code from an assignment, i don't quite understand all of it, but i have to make the program give an option at the end for the user to recall any partnumber and model year/engine no. that was entered.
I have no idea on how to go about doing this task... maybe have some kind of id for each node so i can recall it?
Or is it my only option to rewrite the program using an array or vector data structure?
#include <iostream>
using namespace std;
typedef unsigned long ULONG;
typedef unsigned short USHORT;
// **************** Part ************
// Abstract base class of parts
class Part
{
friend void showPart();
public:
Part():itsPartNumber(1) {}
Part(ULONG PartNumber):itsPartNumber(PartNumber){}
virtual ~Part(){};
ULONG GetPartNumber() const { return itsPartNumber; }
virtual void Display() const =0; // must be overridden
private:
ULONG itsPartNumber;
};
// implementation of pure virtual function so that
// derived classes can chain up
void Part::Display() const
{
cout << "\nPart Number: " << itsPartNumber << endl;
}
// **************** Car Part ************
class CarPart : public Part
{
friend void showPart();
public:
CarPart():itsModelYear(94){}
CarPart(USHORT year, ULONG partNumber);
virtual void Display() const
{
Part::Display(); cout << "Model Year: ";
cout << itsModelYear << endl;
}
private:
USHORT itsModelYear;
};
CarPart::CarPart(USHORT year, ULONG partNumber):
itsModelYear(year),
Part(partNumber)
{}
// **************** AirPlane Part ************
class AirPlanePart : public Part
{
friend void showPart();
public:
AirPlanePart():itsEngineNumber(1){};
AirPlanePart(USHORT EngineNumber, ULONG PartNumber);
virtual void Display() const
{
Part::Display(); cout << "Engine No.: ";
cout << itsEngineNumber << endl;
}
private:
USHORT itsEngineNumber;
};
AirPlanePart::AirPlanePart(USHORT EngineNumber, ULONG PartNumber):
itsEngineNumber(EngineNumber),
Part(PartNumber)
{}
// **************** Part Node ************
class PartNode
{
public:
PartNode (Part*);
~PartNode();
void SetNext(PartNode * node) { itsNext = node; }
PartNode * GetNext() const;
Part * GetPart() const;
private:
Part *itsPart;
PartNode * itsNext;
};
// PartNode Implementations...
PartNode::PartNode(Part* pPart):
itsPart(pPart),
itsNext(0)
{}
PartNode::~PartNode()
{
delete itsPart;
itsPart = 0;
delete itsNext;
itsNext = 0;
}
// Returns NULL if no next PartNode
PartNode * PartNode::GetNext() const
{
return itsNext;
}
Part * PartNode::GetPart() const
{
if (itsPart)
return itsPart;
else
return NULL; //error
}
// **************** Part List ************
class PartsList
{
public:
PartsList();
~PartsList();
// needs copy constructor and operator equals!
Part* Find(ULONG & position, ULONG PartNumber) const;
ULONG GetCount() const { return itsCount; }
Part* GetFirst() const;
static PartsList& GetGlobalPartsList()
{
return GlobalPartsList;
}
void Insert(Part *);
void Iterate(void (Part::*f)()const) const;
Part* operator[](ULONG) const;
private:
PartNode * pHead;
ULONG itsCount;
static PartsList GlobalPartsList;
};
PartsList PartsList::GlobalPartsList;
// Implementations for Lists...
PartsList::PartsList():
pHead(0),
itsCount(0)
{}
PartsList::~PartsList()
{
delete pHead;
}
Part* PartsList::GetFirst() const
{
if (pHead)
return pHead->GetPart();
else
return NULL; // error catch here
}
Part * PartsList::operator[](ULONG offSet) const
{
PartNode* pNode = pHead;
if (!pHead)
return NULL; // error catch here
if (offSet > itsCount)
return NULL; // error
for (ULONG i=0;i<offSet; i++)
pNode = pNode->GetNext();
return pNode->GetPart();
}
Part* PartsList::Find(ULONG & position, ULONG PartNumber) const
{
PartNode * pNode = 0;
for (pNode = pHead, position = 0;
pNode!=NULL;
pNode = pNode->GetNext(), position++)
{
if (pNode->GetPart()->GetPartNumber() == PartNumber)
break;
}
if (pNode == NULL)
return NULL;
else
return pNode->GetPart();
}
void PartsList::Iterate(void (Part::*func)()const) const
{
if (!pHead)
return;
PartNode* pNode = pHead;
do
(pNode->GetPart()->*func)();
while (pNode = pNode->GetNext());
}
void PartsList::Insert(Part* pPart)
{
PartNode * pNode = new PartNode(pPart);
PartNode * pCurrent = pHead;
PartNode * pNext = 0;
ULONG New = pPart->GetPartNumber();
ULONG Next = 0;
itsCount++;
if (!pHead)
{
pHead = pNode;
return;
}
// if this one is smaller than head
// this one is the new head
if (pHead->GetPart()->GetPartNumber() > New)
{
pNode->SetNext(pHead);
pHead = pNode;
return;
}
for (;;)
{
// if there is no next, append this new one
if (!pCurrent->GetNext())
{
pCurrent->SetNext(pNode);
return;
}
// if this goes after this one and before the next
// then insert it here, otherwise get the next
pNext = pCurrent->GetNext();
Next = pNext->GetPart()->GetPartNumber();
if (Next > New)
{
pCurrent->SetNext(pNode);
pNode->SetNext(pNext);
return;
}
pCurrent = pNext;
}
}
int main()
{
PartsList pl = PartsList::GetGlobalPartsList();
Part * pPart = 0;
ULONG PartNumber;
USHORT value;
ULONG choice;
while (1)
{
cout << "(0)Quit (1)Car (2)Plane: ";
cin >> choice;
if (!choice)
break;
cout << "New PartNumber?: ";
cin >> PartNumber;
if (choice == 1)
{
cout << "Model Year?: ";
cin >> value;
pPart = new CarPart(value,PartNumber);
}
else
{
cout << "Engine Number?: ";
cin >> value;
pPart = new AirPlanePart(value,PartNumber);
}
pl.Insert(pPart);
}
void (Part::*pFunc)()const = &Part::Display;
pl.Iterate(pFunc);
cout << "\n\n\nThere are " << pl.GetCount() << " items in the list" << endl;
return 0;
}
I tried using The Find() in the PartsList class. Does Find() take the partnumber and return the address of the part?
I wrote this to dereference the retrieved address, but it gives me the error no match for 'operator<<' in 'std::cout << * show':
int findnumber;
ULONG position;
cout << "Enter Partnumber" << endl;
cin >> findnumber;
Part* show = pl.Find(position, findnumber);
cout << *show;
Am i doing this all wrong? D: Show me please...
The function Find does take a part number, but returns a pointer to a part, which is not the same as the address of the part (that would be a reference, denoted by an &). In addition, Find takes a reference to a variable called 'position', so after calling the Find function, the variable that was passed in for 'position' will contain the value of where the part is in the linked list.
The reason you can't use the << operator, is that it hasn't been provided for the Part class. However, from the source code provided, it looks like the objective is for you to understand Polymorphism and rather than trying to use <<, call the Display function on the part that you have found. e.g: -
Part* part = pl.Find(position, findnumber);
part->Display();
This will display the text for the relevant type of part, so if the part returned was a CarPart, the CarPart's Display function will be called, whereas if the part is an AirPlane part, its Display function is called.
If you wanted to use the stream operator (<<) you'd need to overload the io operators, which you can read more about here.
The class PartsList already has a Find() method that could be used to retrieve any part based on its partnumber. You can then call the Display() method of that part.