Creating inline function in header class to a private variable - c++

I have to make a linked list. I'm not sure if I'm doing this right first of all. But basically the project says I'm not allowed to make a .cpp file but I have to create 4 inline statements through the .h file.
class Queue{
private:
struct QueueNode{
int size;
std::string party;
QueueNode *next;
};
QueueNode *front;
QueueNode *rear;
public:
// Constructor
Queue();
// Destructor
~Queue();
// Queue operations
std::string getPartyName() const { return party; } // This and next 3 lines give error with the private variables
int getSize() const { return size; }
void setPartyName(std::string p) const{ party = p; }
void setSize(int s) const{ size = s; }
};

You are halfway there. You need to declare the functions in the header file, as you have done.
The missing step is that you need to not define the functions within the class body but instead define them below the class declaration using the class name with the scope resolution operator and the inline operator.
The other piece you are missing is that you are declaring functions in your Queue class that are likely meant for your QueueNode struct.
class Queue{
private:
struct QueueNode{
int size;
std::string party;
QueueNode *next;
};
QueueNode *front;
QueueNode *rear;
public:
// Constructor
Queue();
// Destructor
~Queue();
// Queue operations
std::string getPartyName( const QueueNode * const node ) const;
int getSize( const QueueNode * const node ) const;
void setPartyName( QueueNode & out_node, std::string & p);
void setSize( QueueNode & out_node, int s);
};
inline std::string Queue::getPartyName( const QueueNode * const node ) const
{
return node->party;
}
inline int getSize( const QueueNode * const node ) const {
return node->size;
}
inline void Queue::setPartyName( QueueNode & out_node, std::string & p) {
out_node.party = p;
}
inline void Queue::setSize( QueueNode & out_node, int s) {
out_node.size = s;
}
It isn't clear what nodes you intend to set these values for, so I'll fill in the functions with some assumptions.
Either way I think you get the point. If you want to define inline functions within a header class, you cannot define the body within the class itself. You must declare it inline, which is a compiler suggestion, outside the body of the class. I know I didn't complete define the functionality of a linked list, I will leave that to you. But, this should answer the inline question.

Related

C++ How to initialize a struct through no argument constructor

Node is a struct which defined in a class List_set private.
struct List_set::Node
{
element_t str_l;
link_t next_ptr ;
static link_t* find(link_t* current, element_t string_t);
Node();
};
List_set::List_set():link_(nullptr)
{}
List_set::Node::Node():next_ptr{0}
{}
I want to use a constructor to initialize the Node, however the compiler always report an error:
no matching constructor for initialization of 'list_set::List_set::Node'
Can you please help to figure it out?
The next is the definition of class List_set hope it can provide some reference.
class List_set
{
public:
using element_t = std::string;
List_set();
List_set(std::initializer_list<element_t>);
bool is_empty() const;
size_t size() const;
bool contains(const element_t&) const;
void insert(element_t);
private:
struct Node;
using link_t = std::shared_ptr<Node>;
link_t link_;
};

Accessing static member function from friend function

I am using a linked list to implement a set class. In order to hide my struct Node from the users, I put the struct Node declaration into private. Furthermore, I overloaded the operator +, which denotes union operation between two sets. Because I want to implement it by recursion, I overloaded the operator + in the private field called unionMerge. However, it produced an error "error: ‘unionMerge’ was not declared in this scope", but I did put the unionMerge declaration above the operator+ in the Set.cpp file. Could someone help me out?
Set.h is an interface file.
Set.cpp is the implementation for the interface.
Here is the interface file, Set.h:
#ifndef SET_H
#define SET_H
#include <iostream>
using namespace std;
class Set{
public:
Set();
friend const Set operator+(const Set& a, const Set& b);
private:
struct Node{ //private Node
int value;
Node* next;
};
Set(Node *p); //private constructor
Node* list;
//overload the public operator+ above
static Node* unionMerge(const Node* p, const Node *q);
};
#endif
Here is the implementation file, Set.cpp:
#include <iostream>
#include "Set.h"
Set::Set():list(nullptr){
}
Set::Set(Node* p){
list = p;
}
Set::Node* Set::unionMerge(const Node *p, const Node *q){
// to debug, I return nullptr
return nullptr;
}
const Set operator+(const Set& a, const Set& b){
//error: ‘unionMerge’ was not declared in this scope
return Set(unionMerge(a.list,b.list));
Set::Node *p = unionMerge(a.list,b.list);
Set s;
s.list = p;
return s;
}
operator+() is not a member of Set (friends are not members), so if you want to access a static member of Set you have to qualify it:
return Set(Set::unionMerge(a.list,b.list));

how to preserve const correctness across pointers?

I am trying to have a const operation on a class that is truly const - it does not change data that the class points to.
For example:
class Node{
public:
int val;
};
class V{
public:
Node * node; //what is the change that is needed here?
void const_action()const{
node->val=5; //error wanted here
}
void action(){
node->val=5; //error is not wanted here
}
};
You can use a template to enforce the const correctness on a pointer without changing the meaning or the implementation of your class:
template <typename T>
class PreseveConstPointer
{
T *t_;
public:
PreseveConstPointer(T *t = nullptr)
: t_(t)
{
}
PreseveConstPointer<T> * operator=(T *t)
{
t_ = t;
return this;
}
T* operator->()
{
return t_;
}
T const * operator->() const
{
return t_;
}
T * data()
{
return t_;
}
};
class Node{
public:
int val;
};
class V{
public:
PreseveConstPointer<Node> node;
V()
{
node = new Node;
}
~V()
{
if(node.data())
delete node.data();
}
void const_action()const{
node->val=5; // You will get an error here
}
void action(){
node->val=5; // No error here
}
};
const after a function declaration says that the function is not allowed to change any class members (except ones that are marked mutable).
Since your code doesn't change any class member, and only changes the object node points to, both function will compile.
AFAIK there's no way to prevent this. If you mark the node const, neither will compile.
You're confusing Node* const for Node const*.
An [unfortunate?] side effect of using indirection here is that constness of the pointer member has nothing to do with the actual Node on which you're operating.
If you don't need that member to be a pointer, then this is pleasingly easy:
class V
{
public:
Node node;
void const_action() const
{
node.val = 5; // error here
}
void action()
{
node.val = 5; // no error here
}
};
However, given its name, I suspect life is not that simple and you are basically out of luck.

Just a few simple errors

I am getting a few errors that I don't know about and have spent entirely to much time pulling my hair out. Here is my Header:
#ifndef MYBSTREE_H
#define MYBSTREE_H
#include "abstractbstree.h"
#include "MyBSTreeFunc.h"
using namespace std;
template<typename T>
class TreeNode
{
public:
T m_data;
TreeNode* m_right;
TreeNode* m_left;
};
template<typename T>
class MyBSTree:public AbstractBSTree<T> //LINE 18
{
private:
TreeNode<T>* m_root;
public:
void MyBSTree();
int size() const;
bool isEmpty() const;
int height() const;
const T& findMax() const;
const T& findMin() const;
int contains(const T& x) const;
void clear();
void insert(const T& x);
void remove(const T& x);
void printPreOrder() const;
void printPostOrder() const;
void print() const;
};
#endif
And my implementation file:
Line 1-6
void MyBSTree()
{
m_root -> m_data = NULL;
m_root -> m_right = NULL;
m_root -> m_left = NULL;
}
Line 13-21
template<typename T>
bool MyBSTree<T>::isEmpty() const
{
if (m_root== NULL)
return true;
else
return false;
}
Line 28-35
template < typename T >
const T& MyBSTree<T>::findMax() const
{
TreeNode* p = m_root;
while(p -> m_right != NULL)
p = p -> m_right;
return p;
}
The error for line 3 in the implementation says 'm_root' was not declared in this scope. But it's cool with lines 4 and 5. I'm guessing because m_data isn't a pointer? I don't know.
Next, Line 14, and 21, and quite a few others say that it expected an initializer before the '<' token. I assume they are all the same issue so I only put a few here.
Finally, it says for line 18 in the header: "template struct MyBSTree redeclared as a different kind of symbol." It then says Line 1 of my implementation is a previous declaration of 'void MyBSTree". I am assuming those go together.
Thanks for all the help.
You need to fix your constructor declaration:
template < typename T >
classMyBSTree
{
... // some stuff
public:
MyBSTree(); // no return type
... // some stuff
};
You alse need to fix your constructor:
template < typename T >
MyBSTree::MyBSTree() // proper ctor definition
{
m_root -> m_data = T(); // use the initializer for that data type
m_root -> m_right = NULL;
m_root -> m_left = NULL;
}
Lines 1-6: You've define a standalone function in the .cpp named void MyBSTree(). This is not part of the class. It's also bad that you named the function the same as your class. It looks like you want this to be your constructor, in which case you need this (I won't include the template stuff, as it's not the issue):
// in .h
class MyBSTree {
public:
MyBSTree(); // No void
}
// in .cpp
// Uses MyBSTree namespace.
MyBSTree::MyBSTree() { /* initialize your pointers etc */ }
This seems to be your main issue, and may fix the other problems too.
The reason the compiler cannot find m_roots is because your function is not part of the class. You would fix this by putting your function into the class scope with operator :: (e.g. myBSTree::myBSTree(){};)
Template functions cannot be placed in separate files from their class, you need to define all of your template class and function in the same file. Move the implementation of your functions into your header file.

using a data type declared inside a class outside

I am new to c++ so here is verry silly question for few of you.
class DList {
public:
struct DNode {
int data;
DNode* next;
DNode* prev;
DNode(DNode* ptr1, DNode* ptr2, int val)
{
next = ptr1;
prev = ptr2;
data = val;
}
~DNode() {}
public:
DNode* getNext() {return next;}
int getNodeVal() {return data;}
};
This is the DList structure for me.suppose i want to use datatype DNode outside this class in some other cpp file to declare data of DNode type.how can i use it.
It's just a matter of name qualification:
DList::Dnode x;
This also works for externally referring to any variables or functions declared statically within the class.
class DList {
public:
struct DNode {
int data;
DNode* next;
DNode* prev;
DNode(DNode* ptr1, DNode* ptr2, int val)
{
next = ptr1;
prev = ptr2;
data = val;
}
~DNode() {}
public:
DNode* getNext() {return next;}
int getNodeVal() {return data;}
};
static int counter;
static int f() {/**/} //do some stateless operation related to the class
};
//...
DList::counter++;
int result = DList::f();
You can declare a variable of that type with:
DList::DNode myNode;
If you are in some other cpp file, make sure you #include "DList.h" or whatever the name of that (hopefully) header file is. If it isn't a header file, you should move it to one and possibly consider moving the implementation details to a .cpp file.