Trouble accessing class variables - c++

I have a class "poly" and a class "node". The class poly is made from a linked list of nodes. I am trying to pass a poly to a function "printPoly" that will allow me to print the linked list of nodes. But I am having trouble accessing the variables of the nodes...
Here is my code:
class Node
{
private:
double coeff;
int exponent;
Node *next;
public:
Node(double c, int e, Node *nodeobjectPtr)
{
coeff = c;
exponent = e;
next = nodeobjectPtr;
}
};
class poly
{
private:
Node *start;
public:
poly(Node *head) /*constructor function*/
{
start = head;
}
void printPoly(); //->Poly *p1 would be the implicit parameter
};
void poly :: printPoly()
{
poly *result = NULL;
result = this;
double c;
int e;
Node *result_pos = res->start; //create ptr to traverse linked nodes
while(result_pos!= NULL)
{
c = result_pos->coeff; // I CANT ACCESS THESE???
e = result_pos->exponent;
printf(....);
result_pos = result_pos->next; //get next node (also can't access "next")
}
I think it has something to do with the fact that "coeff, exponent, and next" are private variables of the node class. But since my poly class is made up of nodes shouldn't it be able to access these?

Private variables and functions in a class can only be accessed by the function inside that class.
Anything you want to use from outside of that class (e.g. the way you are now) has to be public.

Related

Could someone explain the meaning of vector<Node*>()

I'm solving the Clone Graph in Leetcode, but I encountered a problem inside the following codes
class Node {
public:
int val;
vector<Node*> neighbors;
Node() {
val = 0;
neighbors = vector<Node*>();
}
Node(int _val) {
val = _val;
neighbors = vector<Node*>();
}
Node(int _val, vector<Node*> _neighbors) {
val = _val;
neighbors = _neighbors;
}
};
what does it mean by the statement neighbors = vector<Node*>();. More specifically, vector<Node*>(). Why is it followed by parentheses?
Actually this statement in the constructors of the class Node
neighbors = vector<Node*>();
is redundant.
There is used the move assignment operator that assigns an empty vector created by calling the default constructor vector<Node*>() of the class std::vector<Node *> to the already created empty vector neighbors that is a data member of the class Node.
You may remove this statement from the constructors of the class Node. In fact it has no effect.

How to return pointer from linked list (in Class Template)

I've stumbled upon a problem with my linked list class.
I've one abstract class Shape and multiple classes inheriting from it, like Square or Triangle etc.
I'm storing them in my List class but I don't know how to return stored object back to the pointer of Shape.
Since my explanation may seem pretty vague here is some code with expected behaviour explained.
class Shape // abstract class
{
public:
int a;
//some member virtual methods
};
class Square : public Shape
{
//using the virtual methods from Shape
};
In my main file, this is how I want to use it:
int main()
{
List<Shape*> ShapeList;
Shape *ptr;
Square a(2, 1, 1); // size, x, y coordinates
ShapeList.add(ptr);
//up to this point everything works well
// now I want my list to return a pointer to it's member
// so I can modify it
Shape *listptr;
listptr = ShapeList.findInstanceAt(0); // here's my error
listptr->a = 5; // what I want to do next
}
So as you can see I'm havingtroubles with returning proper value from my list and I don't know how to solve this.
Here's my simplified list implementation:
template <class T> class Node
{
T data;
Node *next;
public:
inline T getData()
{
return data;
}
inline Node* getNext()
{
return next;
}
};
template <class T> class List
{
Node<T> *head, *tail;
public:
List() : head(NULL), tail(NULL) { }
T* findInstanceAt(int _k)
{
if (NULL == head)
{
cout << "\nList is empty.";
return NULL;
}
else
{
Node<T> *temp = new Node<T>;
temp = head;
for (size_t k = 0; k < _k; ++k)
{
if (NULL != temp->getNext()) temp = temp->getNext();
else return NULL;
}
return temp->getData;
}
}
}
Thanks in advance for any suggestions on how to make this work.
#EDIT
Ahh I forgot to add compiler errors that I'm getting:
Error 1 error C2440: '=' : cannot convert from 'Shape **' to 'Shape *'
Do you want to store Shapes or pointers to Shapes in the list? And do you want the findInstanceAt to return the node in the list or a pointer to the node in the list? At the moment you are not consistent on these things
You store Shape* nodes in the list but the findInstanceAt returns a pointer to the node - which is a Shape** object. This is what the compiler is complaining about
You probaly need to chang
T* findInstanceAt(int _k)
to
T findInstanceAt(int _k)

Assign the pointer of one class object to another class object c++

so I am very new to C++ programming so I apologize beforehand if I am asking something trivial. My assignment is to add, multiply and evaluate polynomials where each term of a specified polynomial is represented by a Node class with private variables: double coefficient, int power and Node *next.
class Node{
private:
double coef;
int power;
Node *next;
public: blah
}
The head to that linked list (for each polynomial), is to be stored in an array of Poly objects where the only private variable in my Poly class is Node *head.
class Poly{
private:
Node *head;
public:poly functions;
}
The user is to select the polynomial they want to work with by selecting an element from my polynomial array, and this will give the head to the selected polynomial.
poly_array[n];
However my issue now is that the element of this array is of object Poly and I want to make it of class Node so I can actually extract its contents of the class and use this method to transverse through the nodes of the selected polynomial(s).
This is the code I have tried to implement to make this work but my function call of convert poly returns garbage. I am lost as to what method I should try next. Thank you in advance.
This is where I try to first transverse a polynomial to display its contents.
void init_polydisplay(vector<Poly*> polynomial_array, int numofpolys)
{
Poly *polyobject;
Node *polyhead;
for (int n = 0; n < numofpolys; n++)
{
temp3.getnodehead();
polyhead=polyobject->convertPoly(polynomial_array[n]);
}
}
My attempt at trying to return Node* versus just the head of the polynomial.
Node* Poly::convertPoly(Poly* tmp)
{
return (Node *) tmp;
}
You can define a get_head() function in Poly
class Poly{
private:
Node *head;
public:
Node * get_head()
{
return head;
}
};
and use it this way:
polyhead = polynomial_array[n]->get_head();

How to properly use protected in singly linked list

I've successfully programmed a singly linked list by the following program:
The header file is:
#ifndef SLL_H_
#define SLL_H_
#include <iostream>
class node {
protected:
public:
int key;
node *next;
node();
~node();
};
class SLL : public node{
private:
node *Head = NULL;
int SLL_SIZE = 0;
public:
//Constructor
SLL();
//SLL(int n);
//Destructor
~SLL();
//Modifiers
void Push_Front(int a);
void Push_Back(SLL A,int b);
void Traverse();
//Access function
int SLL_size();
int Get(node* p);
//Iterator
node* Begin();
node* End();
//void Search(int a);
};
#endif
SLL.cpp
#include "SLL.h"
#include <iostream>
using namespace std;
node::node(){
cout << "Empty constructor of node is being called;" << endl;
}
node::~node(){
cout << "Empty destructor of node is being called;" << endl;
}
SLL::SLL():node(){
cout << "Empty constructor of SLL is being called;" << endl;
}
SLL::~SLL(){
cout << "Empty destructor of SLL is being called." << endl;
}
//Insert element at the front of the list
void SLL::Push_Front(int k){
node *temp = new node [1];
temp->key = k;
temp->next = Head;
Head = temp;
SLL_SIZE = SLL_SIZE + 1;
}
//Insert element at the end of the list
void SLL::Push_Back(SLL A, int m){
node *temp1 = A.End();
node *temp2 = new node [1];
temp2->key = m;
temp1->next = temp2;
temp2->next = NULL;
SLL_SIZE = SLL_SIZE + 1;
}
//Insert element at a given position
//Return the number of elements in the linked list
int SLL::SLL_size(){
return SLL_SIZE;
}
//Traverse the list (print the list)
void SLL::Traverse(){
node *temp;
temp = Head;
while(temp!=NULL){
cout << temp->key << " ";
temp = temp->next;
}
cout << endl;
}
//Get key given pionter
int SLL::Get(node* pt){
if(pt!=NULL){
node* temp = pt;
return temp->key;
}
else {
cout << "Null pointer points to nowhere!" << endl;
return 0;
}
}
//Return the pointer at the beginning of the list
node* SLL::Begin(){
return Head;
}
//Return the pointer at the end of the list
node* SLL::End(){
node* temp = Head;
while(temp->next!=NULL){
temp = temp->next;
}
return temp;
}
main.cpp
#include <iostream>
#include "SLL.h"
using namespace std;
int main()
{
SLL A;
A.Push_Front(1);
A.Push_Front(2);
A.Push_Front(5);
A.Push_Front(6);
A.Push_Back(A,3);
A.Traverse();
cout << A.SLL_size() << endl;
cout << A.Get(A.Begin()) << endl;
cout << A.Get(A.End()) << endl;
return 0;
}
One error is, for example :
SLL.h||In member function 'void SLL::Push_Front(int)':|
SLL.h|7|error: 'int node::key' is protected|
SLL.cpp|25|error: within this context|
SLL.h|8|error: 'node* node::next' is protected|
SLL.cpp|26|error: within this context|
SLL.h||In member function 'void SLL::Push_Back(SLL, int)':|
SLL.h|7|error: 'int node::key' is protected|
SLL.cpp|35|error: within this context|
SLL.h|8|error: 'node* node::next' is protected|
LL.cpp|36|error: within this context|
SLL.h|8|error: 'node* node::next' is protected|
SLL.cpp|37|error: within this context|
Similar error for the other member functions that employed key and next.
This program works very well now. However, after I moved the 2 lines in node class, int key; node *next; under protected, then it gives me error such as "node::key is protected".
First, please don't blame me for doing something stupid :P . I know if I struct for the node then life will be much easier. I am trying to practice inheritance and to understand protected. That's why.
By definition, protected members can be accessed by derived class, right? I don't know where I am doing it wrong.
Hope you can help me out. Thanks!
The protected keyword allows an inheriting class to see the protected members. That means instances of the inheriting class can see the protected members of themselves, as well as the protected members of other instances of that same inheriting class. It does not extend this access through pointers to the parent class type, because that access isn't safe.
Let's make that concrete. Consider the following example:
class A
{
protected:
int a_int;
};
class B : public A
{
public:
int good()
{
return a_int; // OK: Protected member of this instance
}
int bad( A *a_ptr )
{
return a_ptr->a_int; // BAD: Can't access the protected member
// through a pointer to the parent class type.
}
int also_good( B *b_ptr )
{
return b_ptr->a_int; // OK: Pointer to the same class type as this
// class is safe.
}
};
The errors in your code look like the second case. So why is the second case illegal, but third case OK?
The second case is illegal because the compiler doesn't know the actual type of object the A* points to. It could be any descendent of A, and may not even be convertible to B*. Therefore, the access extended by the protected clause isn't guaranteed to be safe or meaningful. For example, suppose you had
class C : public A { ... };
class D : public C { ... };
and you passed a C* or a D* into method bad() above. It doesn't seem reasonable that B should be able to see the protected members that were exposed to C, since C and B aren't directly related. The same holds true for D.
But, in the third case, the compiler knows for certain it has a pointer to a B or a class derived from B, so it knows that the access extended by the protected keyword is safe and meaningful. By that, I mean that the protected fields are managed in the way B expects them to be managed. In fact, without that access, you would have a hard time writing binary operators involving two instances of B
Make sense?
In case you're still not convinced: Suppose I made two parallel classes, both which inherit from node:
// plain singly linked list
class normal_sll : public node { };
// singly linked list that stores all of its elements negated
class negative_sll : public node { };
Sure, it's a contrived example, but bear with me. Because both classes derive from node, you could pass either class through a node *. So, you could pass an instance of negative_sll to normal_sll or vice versa.
C++'s access control prevents either class from looking at the protected fields through that node *, though. And that's good, because negative_sll manages them differently than normal_sll.
But, you can't pass an instance of negative_sll through a normal_sll* or vice versa. So, you know if you have a normal_sll* inside one of normal_sll's methods, you know it's safe to access the protected members.
Sure, it's a contrived example. I'm sure you could think of a better one. Make sense, though?
Now you could make B a friend of A and override this control. But, this would let B see the private members of A, totally bypassing the protected concept. A better solution would be to rewrite your SLL code so that you pass SLL*, not node* to its methods.
First of all, I don't see, why you want to derive SLL from Node at all, as a List is not a specialization of a Node. What you probably want to do instead is to make SLL a friend of Node:
class node {
protected:
int key;
node *next;
public:
friend SLL; //This allows SLL to access node's private and protected members
node();
~node();
};
As far as your question - why SLL can't access Node's protected members - is concerned:
--------- EDIT: My explanation was just wrong ------------

Mixing abstract classes and templates, a recipe for disaster?

I'm having problems with the following situation. I have three classes that are involved in this mixup. List, ListNode, City. I have a List<City *>, where the list will be made up of a set of ListNode<City *> (standard wrapper around the list nodes).
City is an abstract class, so there are several classes that inherit from it that could be placed in this list and accessed polymorphically. The List class has a getHead() method which returns a pointer to a ListNode that is the head.
Any city has a population, so to access the populations, I'd expect the following to work. It's not, thus my question. I broke it down into pieces to make it simpler along the way:
ListNode<City *> *head= country->city_list->getHead();
City *headnode = *head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
getPopulation() returns an integer. country is defined as List<City*> *city; Any help on how I could figure out my problem would be greatly appreciated.
edit adding more code for better idea of what I'm working with. First, ListNode:
template <class T>
class ListNode
{
public:
ListNode() {next = 0;node = 0;};
ListNode(T *t) {node = t; next = 0;};
ListNode(const ListNode &l)
{
//long copy constructor. snip.
};
T *getNode() const { return node; }
ListNode *getNext() const { return next; };
private:
T *node;
ListNode *next;
};
Now, here is what might relevant in the List class..
template <class T>
class List
{
public:
List()
{
head = 0;
size = 0;
};
List(ListNode<T> *t)
{
head = t;
size = 1;
};
List(T *t)
{
head = new ListNode<T>(t);
size = 1;
};
List(const List<T> &t)
{
// long copy constructor. snip.
};
//bunch of irrelevent methods.
ListNode<T> *getHead() const {return head;};
List &operator+=(T &t)
{
this->insert(&t);
size++;
return (*this);
};
private:
List &insert(T *t)
{
ListNode<T> *current = head;
if (current == 0)
{
head = new ListNode<T>(t);
}
else
{
while (current->getNext() != 0)
{
current = current->getNext();
}
current->setNext(new ListNode<T>(t));
}
return (*this);
};
ListNode<T> *head;
int size;
};
I have a hunch that the process of inserting might be the problem. I insert with the List class's += operator, shown in the List implementation above. It calls the private insert method shown above, as well. It looks like this:
City *somecity = new City(x,y,z); //some parameters. integers.
*city_list += somecity; // where city_list is a List.
I think you've got a variable scoping problem.
Your ListNode class contains a pointer to the node value. Your ListNode constructor takes in a pointer to the node value and saves it.
The problem is if that pointer is to a local variable that then goes out of scope. Your ListNode's node pointer is now pointing to an object that doesn't exist. e.g. in this example
addToList(List<int>& myList)
{
int x = 3;
myList += x; // pointer to x is in the list
}
// Out of scope; x no longer exists, but myList has a pointer to it.
// Accessing this node will result in an error.
There are a couple possible remedies:
Have your ListNode contain values rather than pointers. The drawback here is that you will be making copies of the values
Implement ListNode using a reference counted smart pointer which will manager the lifetime of the object.
Well, what you could do is:
ListNode<City *>* head = new ListNode<City*>(country->city_list->getHead());
City* headnode = head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
It will take the existing City (on the memory) and put it at the head of the List node, and so on.
and if you want to copy them, maybe you could just make this:
ListNode<City *>* head = new ListNode<City*>*(new City(country->city_list->getHead()));
City* headnode = new City(head->getNode());
cout << "Test: " << headnode->getPopulation() << endl;
Hope it will help you.