How to make methods from parent class use a different variable? - c++

I have a class like this:
class A {
protected:
class Node {
public:
int x;
Node* next;
};
Node* root;
.
.
.
};
And a lot of methods using this "root".
Now, say I want to inherit from A class, and make all the methods use a "better" node. Something like:
class B : public A{
class NewNode : public A::Node{
public:
int y;
};
NewNode* root;
.
.
.
};
Is there a way of doing something like this? And if not, what are the alternatives (beside rewriting A class)?
Thank you!

Since NewNode is derived from Node you can put something like this in the B constructor
delete root; //remove the Node
root = new NewNode(); //and put in the better one
More realistically, you'll probably need something like this
Node * oldRoot = root;
root = new NewNode(oldRoot);
delete oldRoot;
You don't need a new variable in B, just use A::root.

If A is abstract, it can be compiled and used with all its methods independently from any derived classes. Therefore, code that accesses this variable will already be generated and cannot change. I think there is really no way to do what you want to do, without modifying A.
Although, it depends a little bit, what exactly you mean. If NewNode is derived from Node and Node has virtual functions, A will of course call the methods of NewNode. If you don't want NewNode to be derived from Node, you probably have to make A a template class. This would also work, if A accesses members of Node directly, instead of using virtual Getter/Setter-Functions.

Related

How to declare a pointer within a class definition to the class being defined?

I am new to C++, and I am learning classes now. I have found this class and wondering how works object created as a pointer in its own class. Can you guys explain it please? Where and how can it be used?
class Car {
public:
int weight;
const char* model;
Car* other;
};
This can be used for example in a linked-list where a Node of the list has to also hold a reference to the next Node in the list.
class Node
{
public:
int value;
Node* next;
};
class LinkedList
{
public:
Node head;
}
The reason why the next Node is a pointer here is that the class is not yet fully defined and thus the compiler doesn't know its size. But since pointers have always a fixed size, we can store a Node* as a class member just fine.
class Car {
public:
// ...
Car* other;
};
At the moment of declaring the data member other, the Car class is actually an incomplete type (i.e., it is not completely defined). As a result, the compiler doesn't know the size of a Car object yet. However, since this data member other is a pointer to a Car object rather than a Car object, the compiler does know the size of other.

The function with different parameters in C++ Inheritance and Polymorphism

Recently, I am learning Inheritance and Polymorphism in C++.
I made three classes: Node, uni_dir_Node(uni-direction Node), and bi_dir_Node(bi-direction Node).
Here is my code:
class Node {
protected:
string name;
Node* next;
virtual void connect(Node* _Node) = 0;
};
class uni_dir_Node : public Node {
void connect(Node* _Node) {
this->next = next;
}
};
class bi_dir_Node : public Node {
Node* previous;
void connect(Node* next_Node, Node* previous_Node) {
this->next = next;
this->previous = previous_Node;
}
};
int main()
{
Node* head = new bi_dir_Node;
return 0;
}
Of course there is a compiler error in this code.
My question is, the function connect() in class uni_dir_Node has one parameter but for the function connect() in class bi_dir_Node has two parameters. How do I keep this inheritance structure and make it legal?
Is there any good way to solve this problem?
As others have said, the problem is that bi_dir_Node doesn't have a void connect(Node* _Node) method.
Conceptually, what's going on is that inheritance indicates an "is a" relationship. Saying that bi_dir_Node inherits from Node means that bi_dir_Node is a Node, so anything that a Node can do, a bi_dir_Node can do.
You're trying to say that bi_dir_Node is a Node but that it can't do everything a Node can: specifically, it can't Connect with a single argument.
The solution is to either provide a single-argument Connect for bi_dir_Node or to remove or redesign the inheritance structure. For example, in C++, templates may be a better approach: you can make uni_dir_Node and bi_dir_Node completely separate (not part of the same inheritance hierarchy) and write template classes and template functions that are generic enough to operate on both.
As says nwp, to have polymorphism, you need to have functions with the same prototypes in the derived classes.
By prototype, it means :
same return type
Same parameter list
const keyword at the end of the prototype must be present on derived if present on base method
same method name of course
This is because all functions need to be called the same way and same semantic whether it is a base or derived object.
virtual key word must be put on the base class method prototype.
The virtual behavior is inherited. So it can be put or not on derived class overriden methods.
Advanced stuff - not often useful :
Since C++ 98 (prehistory !), if a base class method is
Base * Method();
The derived method can be :
Derived * Method();
This is because Derived* IS A KIND of Base*
Hope it clarifies

C++: Leaving open option for a pointer to point to one of two types

In C++, I have two classes: Node and RootNode. I would like to have a member for Node that can be a pointer to either Node or RootNode. Is there any way I can leave open the option for a pointer to point to one of two different classes without needing to commit to one of them until I set the value of that pointer?
I have seen some answers using union; I am not sure these will work, since to use a variable defined using a union I will have to know whether it is pointing to a Node or RootNode so I know which object of union to reference (union_typedef.node or union_typedef.rootnode). I want to be able to use this pointer without needing to know whether it is pointing to a Node or a RootNode.
There is a way to do what you want to do, and a way to do what you probably need to do (and these two are different things).
To do what you want (set a pointer of one of two types) use union:
struct MyStruct {
union {
Node *nodePtr;
RootNode *rootPtr;
}
};
Above, you can set either nodePtr or rootPtr, but the union will take space of a single pointer.
What you probably need, however, is a class inheritance with virtual functions, and a pointer to base class:
struct Node {
virtual void doSomething() {
cout << "I'm a node" << endl;
}
};
struct RootNode : public Node {
virtual void doSomething() {
cout << "I'm a root" << endl;
}
};
You can make a pointer to Node, and assign it a pointer to Node or to RootNode. No matter what you assign, the call of doSomething() will be routed to a correct function:
Node *n = new Node();
n->doSomething(); // Prints "I'm a node"
delete n;
n = new RootNode();
n->doSomething(); // Prints "I'm a root"
delete n;
Neither Node nor RootNode derive from the other.
If the derivation hierarchy is fixed and you cannot change it, you can build wrapper classes for Node and RootNode, have one wrapper derive from the other (or have them both derive from a common ancestor), and make virtual functions that dispatch to the functions of wrapped objects.
Sure. Use a Union!
union { Node *nodePtr; RootNode *rootNodePtr; } unionNodePtr;
Does RootNode derive from Node, or vice versa?
If so, then simply declare your member as which type is the "base" type. For example:
class Node
{
public:
Node *member;
};
class RootNode : public Node
{
};
If not, you will have to use a union instead:
class RootNode
{
};
class Node
{
public:
union {
RootNode *root;
Node *node;
} member;
};

If I'm using a private struct, how do I declare it as an argument for the member functions listed above as public?

VS is not happy with the "Node*" argument for "makeEmptyHelper" because it does not 'see' the struct I guess.
public:
void makeEmpty(); // make the tree empty so isEmpty returns true
void makeEmptyHelper(Node*);
private:
struct Node {
NodeData* data; // pointer to data object
Node* left; // left subtree pointer
Node* right; // right subtree pointer
};
Node* root; // root of the tree
You can't do that. I see two possible things you're trying to accomplish:
Have makeEmptyHelper be accessible publicly but hide the contents of struct Node. In that case, you should either declare the fields of struct Node as private, or declare struct Nodeas public but only define its members in your implementation file.
Have makeEmptyHelper be a helper function for another member function. In that case, make it private.
That's correct. You cannot have a function publicly available while it's argument is private. Either make the type of the argument public as well or make the method private.
The Node struct is an argument of a public method of your class.
Therefore the Node struct is something that will be public outwards.
So the Node struct shall be public.

C++: How to have a different class function manipulate my class member variable

I am probably missing something very simple, but I'll be very grateful if someone can point me in the right direction.
I have 2 classes: A and B. A has a collection of data structures and functions that modify them (for a hypothetical example, say add, delete, insert, etc to the data structures). B has a collection of functions that specify how the data structures are modified in A.
For the sake of extensibility, B is inherited to reflect different possible behaviors on A's data structures. One implementation of B may choose to add to the beginning of A's data structure, delete from the end, and so on. Another implementation might add to the end, delete from the beginning, and so on.
I am passing an object of base class B during the creation of A, so that the generic addNode(), deleteNode(), and other functions of A can actually look up the particular type of B object passed to it during creation and refer to its implementation in B as to what action to follow.
In this hypothetical example below, the data structure in concern is a doubly linked list. In my problem, the data structure itself is not the issue. I am concerned about how to call the correct method in derived class of B to modify my data structure in A.
Class A:
class A
{
static A create(B bObj); // returns an A object after calling the constructor
void addNode(int);
void deleteNode();
...
private:
struct myNode
{
int value;
myNode *next;
myNode *prev;
}
myNode *head;
myNode *tail;
}
Class B:
class B
{
virtual void addNode(int);
virtual void deleteNode();
...
}
Class ChildB1:
class ChildB1
{
void addNode(int)
{
// code for add to the front
}
void deleteNode()
{
// code for delete from the back
}
}
Class ChildB2:
class ChildB2
{
void addNode(int)
{
// code for add to the back
}
void deleteNode()
{
// code for delete from the front
}
}
The problem I am running into is how to give a child class of B access to the current object of A I am operating on? Let's say, while creation of the object of A (aObj) with the create() method, I passed a reference to object ChildB2.
B *bObj = new ChildB2();
A aObj = A.create(*bObj);
Now when I call aObj.add(), I want it to call the add() method of ChildB2 class, so that it can operate on the linked list in A and add it to the back end of the list. But how does the add() function of ChildB2 class access the linked list of aObj?
I apologize if the question is long-winded and naive. I am happy to give further clarification if required.
Add B as a friend of A.
class A
{
friend class B;
// the rest
};
Since friendship is not inherited, B has to explicitly provide its heirs with access to A private parts.
class B
{
protected:
// since A::myNode is private, redeclare it here
// for heirs
typedef A::myNode myNode;
// access to A parts
void getAParts (A*, myNode*** head, myNode*** tail)
{
*head = &a->head;
*tail = &a->tail;
}
// the rest
};
A couple of notes: you should pass B to create by reference, not by value, otherwise your ChildB2 object will be sliced. You also need to manage Bs lifetime somehow.