How to manipulate the object a pointer represents C++ - c++

I am building a data structure and need to manipulate the object indicated by a pointer. The object indicated by the pointer is:
//in header file
struct treeNode{
int value;
treeNode* left;
treeNode* right;
};
My current implementation only changes what the pointer is pointing to.
target->value = oneLarger->value
Target and oneLarger are defined:
void method(treeNode* target){
treeNode* oneLarger = (tree node retrieved by another method)
target->value = more->value
}
Is this possible to do via pass by reference or do I have to pass by value?

You can do: by Pointer, by Ref, by Copy
note that changes made in the byCopy function will get lost as soon as the function is done!
Those options look like:
//by Pointer
void method(treeNode* target) {
treeNode* oneLarger = ...
target->value = oneLarger->value;
}
//by Ref
// since that is a ref, you access the value using the dot(.) and not the `->` operator
void method(treeNode& target) {
treeNode* oneLarger = ...
target.value = oneLarger->value;
}
//by Copy
// since that is a copy, you access the value using the dot(.) and not the `->` operator
void method(treeNode target) {
treeNode* oneLarger = ...
target.value = oneLarger->value;
}

Related

Modifying private pointer of object within same type (but different object) public method

I've been attempting to create a node class which mimics a node on a graph. Currently, storage of the predecessor and successor nodes are stored via a node pointer vector: std::vector<Node*> previous. The vectors for the predecessor/successor nodes are private variables and are accessible via setters/getters.
Currently, I am dealing with updating the pointer values when adding a new node. My current method to update the predecessor/successor nodes is through this method (the method is the same for successor/previous nodes, just name changes):
void set_next(std::vector<Node*> new_next) {
this->next.clear();
for (Node* node : new_next) {
this->next.push_back(node);
}
}
This works for the current node but I was wondering the best way to update the new_next nodes that are passed in, especially the most 'C++'-esque way to accomplish this. I have previously written a method which adds individual nodes to the successor/predecessor vector:
void add_next(Node* new_node, bool one_way = false) {
this->next.pushback(new_node);
if (!one_way) {
new_node->add_prev(this, one_way = true);
}
}
The one_way variable was used to determine the depth(?) of the add_next() call. If it is true, it will add to the successor set and then add to the predecessor set of new_node. Since the boolean value is set to false when the new_node->add_next() method call occurs, it will only add to the predecessor set and not attempt to call add_next()/add_prev() again. This solution does work, but I'd rather not have the one_way variable and would prefer that the method would be private.
Here is the structure of the class currently:
class Node {
private:
std::vector<Node*> previous;
std::vector<Node*> next;
boost::any data;
public:
std::vector<Node*> get_previous()
void set_previous(std::vector<Node*> new_previous)
std::vector<Node*> get_next()
void set_next(std::vector<Node*> new_next)
void add_prev(Node* new_node, bool one_way = false)
void add_next(Node* new_node, bool one_way = false)
}
Avoiding the one_way parameter, it seems my best solution would be to just create an add_next/add_prev method that only updates the current node, not the passed node, unlike the solution above. With this solution, when adding new nodes, I could call the inverse of the add_next/add_prev on the new node. However, I have an inkling there may be a better solution for this.
Thank you!
I think this should get you going (edge-cases left to you to figure out, if any):
template<typename T>
class Node {
// Everything made public for debugging purposes, change this to fit your needs
public:
std::vector<Node<T>*> previous;
std::vector<Node<T>*> next;
T data;
Node(T val) {
data = val;
}
void set_next(std::vector<Node<T>*>& new_next);
};
template<typename T>
void Node<T>::set_next(std::vector<Node<T>*>& new_next) {
next = new_next;
for (Node<T>* node : new_next)
node->previous.push_back(this);
}
int main() {
// Little proof of concept where 0 is parent to 1, 2, 3
Node<int> one = 1;
Node<int> two = 2;
Node<int> three = 3;
Node<int> zero = 0;
std::vector<Node<int>*> new_next = { &one , &two, &three };
zero.set_next(new_next);
return 0;
}
To sum up the differences:
Use templates, boost::any is non standard and is all around terrible for this task.
Leverage operators (= makes a copy of std::vectors).
Leverage reference types (this way you can modify the argument passed to your function).

c++ how to return a ptr to int from a pointer which is pointer to a struct

i am c++ beginner student, i have a problem in my c++ lab assignment.
I have no ideas how to return a pointer to int from a pointer, which is pointer to the struct.
my header file
class list {
public:
/* Returns a pointer to the integer field
pointing to the first node found in list
with value val. Returns 0 otherwise */
int *find(int val);
private:
list_node *the_list;
}
my cpp file
int* list::find(int val)
{
while(the_list)
{
if(the_list->value == val)
{
// i try to return the pointer that is type pointer to int.
// the_list is a pointer to a struct type call list_node.
int * ptr = the_list;
return ptr;
}
the_list = the_list->next;
}
return 0;
}
struct list_node
{
int value; // data portion
list_node *next; // pointer next portion
list_node *previous; // pointer previous portion
};
the_list is not a pointer to int, it's a pointer to list_node, so int *ptr = the_list; is not correct.
To get a pointer to the value, do:
int *ptr = &(the_list->value);
Beware your find function moves the pointer to the internal list which is bad. You should use a private variable, and return the address of the value member:
int* list::find(int val)
{
for(list_node *node = the_list; node != nullptr; node = node->next)
{
if(node->value == val)
{
// i try to return the pointer that is type pointer to int.
// the_list is a pointer to a struct type call list_node.
return &node->value;
}
}
return nullptr;
}

How to retrieve pointer structure in a function

I have a struct like this:
struct ClientNode
{
string name;
int flightnumber;
int clientno;
ClientNode * right;
ClientNode* left;
};
then I have declared a pointer of this struct:
ClientNode* root = new ClientNode;
in a function I have initialized clientno for root like this:
root->clientno = 11;
and then I want to send root as an argument to a function:
ClientNode newnode;
root = Insert_to_AVL_Tree(&newnode, root);
and here is my Insert_to_AVL_Tree:
ClientNode* clientclass::Insert_to_AVL_Tree(ClientNode* Node, ClientNode* root)
Here is where the error happens, I have initialized root->clientno but it seems that it changes when I pass it to another function thus it can't compare to values in the if, also node->clientno has the correct value that has been read from a file in another part of my code:
if (Node->clientno < root->clientno)
root->left = Insert_to_AVL_Tree(Node, root->left);
what is the correct way to get the root->clientno value in another function?
here is the value shown for root->clientno
here is the value for node->cleintno
For passing Pointer to functions the best way I use is double pointer
void clear(int **p)
{
*p = 0;
}
int main()
{
int* p;
clear(&p);
return 0;
}

How to build a C++ Stack structure

struct Node{
int value;
Node *next;
Node(int val) :value(val), next(nullptr){}
};
class Stack
{
public:
void push(int val);
int pop();
bool is_empty(){ return first == nullptr; }
private:
Node *first = nullptr;
};
int Stack::pop(){
int ret = first->value;
first = first->next;
return ret;
}
void Stack::push(int i){
if (is_empty()){
first = &Node(i);
return;
}
Node oldFirst = *first;
first = &Node(i);
first->next = &oldFirst;
}
Here is how I wrote the code, however, there is a problem that when I finished push() the pointer of first isn't point to the right object. I'm wondering how I can solve that problem.
The expression &Node(i) creates a temporary object and give you a pointer to it. And then the temporary object is immediately destructed, leaving you with a pointer to a non-existing object.
You need to use new to allocate a new object.
You have a similar problem with &oldFirst, which give you a pointer to a local variable, which will be destructed once the function returns. You need to use a pointer variable.

C++ problems with conversion

I have one semestral work (own double linked list) and our teacher want this definition of class DoubleList:
template <typename T> //just part of all methods
class DoubleList {
public:
DoubleList(void); //We HAVE TO follow this definitions
void AddFirst(const T &); //const!
T &AccessActual(void);
T RemoveFirst(void);
}
My question is, how can I define a node? AddFirst have const argument and other methods haven't. Data must be set in constructor and then they can't be changed. Is this task so limited or are here other ways to complete the task?
Here is my actual Node:
template <class U>
class Node{
Node<U> * next;
Node<U> * previous;
const U * data;
public:
Node(const U *data){ //
next = NULL;
previous = NULL;
this->data = data;
}
void SetNext(Node<U> *next) {
this->next = next;
}
Node<U> *GetNext(){ return next; }
void SetPrevious(Node<U> *previous) {
this->previous = previous;
}
Node<U> *GetPrevious(){ return previous; }
const U *GetData() { return data; }
};
In containers, it's usually better to have a copy of the data so change const U * data; to U data;
The Node constructor would be easier to use if it had this signature Node(const U& data). No pointers.
The GetData would also have to change. Return a reference. U& GetData().
It is dangerous to hold addresses of data items. If the user of the lists wants that functionality he can use a list that stored pointers (e.g. U=int*)
Your node class seems fine, although i would keep using template argument T instead of U, right now it is confusing.
Your AddFirst() method should simply create a new node and assign the correct next pointer to the new node and the correct prev pointer to the "old" first node and adjust the actual object? what does that refer to?
Your interface of nodes differs from this one returning a reference instead of a pointer. I find it quite strange that the AccessActual can always return an object, while when the list is empty this can be a nullptr??
example implementation:
void AddFirst(const T &)
{
Node<T>* newNode = new Node<T>(T);
Node<T>* current = &AccessActual(); // how can there be an actual when the list can be empty or is that impossible?
{
while( current.GetPrev() != nullptr )
{
current = *current.GetPrev();
}
current.SetPrev(newnode);
newnode->SetNext(current);
}
}