I'm trying to create an implementation of a LinkedList that represents polynomials. The Linked list is going to be a list of "Term"s. A term is an implementation of Data (which is an abstract class with methods: compareTo() and toString()). The Polynomial class has a variable called head which I am trying to initialize as a Term. My compiler is saying that I "cannot declare member of abstract type: Term", but I did not think Term was abstract because it is an implementation of Data (the abstract class). If you guys could take a look at this and let me know of any huge red flags I'm missing, I would greatly appreciate it.
Collection.h:
class Data {
public:
virtual ~Data() {}
virtual int compareTo(Data * other) const = 0;
virtual string toString() const = 0;
};
class Term : public Data {
public:
int coefficient;
string variable1;
int exponentX;
string variable2;
int exponentY;
Term * next;
Term(int coeff, string var1, int exp1, string var2, int exp2, Term * next) :
coefficient(coeff),
variable1(var1),
exponentX(exp1),
variable2(var2),
exponentY(exp2),
next(next) {};
string convertInt(int number) {
stringstream ss;//create a stringstream
ss << number;//add number to the stream
return ss.str();//return a string with the contents of the stream
}
int compareTo(Term * term) {
if(this->exponentX > term->exponentX) {
return 1;
}
else if(this->exponentX < term->exponentX) {
return -1;
}
else {
if(this->exponentY > term->exponentY) {
return 1;
}
else if(this->exponentY < term->exponentY) {
return - 1;
}
else {
return 0;
}
}
}
string toString() {
stringstream s;
int * current = &this->coefficient;
if(*current == 1 || *current == -1) {
}
else if(coefficient != 0) {
s << convertInt(coefficient);
}
else { return s.str(); }
if(variable1 != "" && this->exponentX != 0) {
s << variable1;
s << convertInt(exponentX);
}
if(variable2 != "" && this->exponentY != 0) {
s << variable2;
s << convertInt(exponentY);
}
return s.str();
}
};
Also, here is implementation of LinkedList. There are some other methods in there, but they don't seem to be giving any issues.
LinkedList.cpp:
class Polynomial : public LinkedList {
public:
Term head;
Polynomial() {
this->head = NULL;
}
~Polynomial() {
Term * current = head;
while (current != NULL) {
Term * next = current->next;
delete current;
current = next;
}
}
Thank you!
When you are overriding virtual methods, you have to match the function signatures precisely. The return type may vary in accordance with covariance rules, but the parameter types must be exactly the same.
In the base class Data function compareTo is declared as
virtual int compareTo(Data * other) const
In the derived class Term it is declared as
int compareTo(Term * term)
Firstly, the parameter type is different. Secondly, the const is missing.
This means that you wrote a completely unrelated function in the derived class. It does not override the base class's pure virtual function. Since the base pure virtual function remain non-overriden, class Term is still abstract.
In Term you have to declare your function precisely as
int compareTo(Data * other) const
I assume that you expect to use compareTo in Term only for Term-to-Term comparisons. But in this design you'll have to either receive Data as an argument and then cast it to Term, or use the double-dispatch technique.
P.S. On top of that you declare a Term object as a member head of your Polynomial class and then later use it as if it is a pointer
Term * current = head;
This makes no sense at all. If you want your head to be a pointer, declare it as a pointer. If you want it to be an object, then stop using it as a pointer. Either this or that.
Related
I think the title says it all. The error MSVS showing is
a nonstatic member reference must be relative to a specific object
My code:
struct Node
{
Node(size_t id, int length, int size);
size_t id_;
int length_;
std::vector<Node*> children_;
};
class SuffixTree
{
public:
SuffixTree();
void printSuffixes();
void printSuffixes(Node* current = root_); // ERROR
~SuffixTree();
private:
Node *root_;
};
There are a few more methods similar to these such that I want the user to call these methods from main but since root_ is private, I had to overload all those methods and the user now calls the overloaded methods instead. The definition of these methods are simply like:
void SuffixTree::printSuffixes()
{
printSuffixes(root_);
}
Any solution?
Edit:
void SuffixTree::printSuffixes(Node* current)
{
if (current == nullptr)
return;
if (current->length_ == -1)
std::cout << "leaf" << std::endl;
for (size_t i = 0; i < current->children_.size(); ++i)
printSuffixes(current->children_[i]);
}
Default arguments have quite a few restrictions.
Instead, consider using nullptr as the default:
void SuffixTree::printSuffixes(Node* current = nullptr)
{
if (current == nullptr)
current = root_;
// ...
}
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)
I am beginning a basic implementation of a template LinkedList class. When I compile the header file alone with g++ there is not problem. However, when I try to compile with another class that implements a certain type of the linked list, it gives me an error. It seems to want to compile an object of the type of the node. Why would it do so? The Node constructor doesn't call the constructor of the template type.
I will post all the relevant header files. There may be extraneous code, but I wanted to show what is being used. I will post the error message followed by the linked list implementation, then the class that uses the linked list, and then the ParkingLot constructor that is mentioned in error.
Here is the error message:
LinkedList.h: In instantiation of ‘Node<T>::Node(T) [with T = ParkingLot]’:
LinkedList.h:46:9: required from ‘void LinkedList<Type>::addNode(Type) [with Type = ParkingLot]’
Decal.h:20:28: required from here
LinkedList.h:13:16: error: no matching function for call to ‘ParkingLot::ParkingLot()’
Node(T input) {
^
LinkedList.h:13:16: note: candidates are:
In file included from Decal.h:2:0,
from test.cpp:3:
ParkingLot.h:28:2: note: ParkingLot::ParkingLot(int, std::string, int, int, int, int)
ParkingLot(int num_spaces, std::string name, int x, int y, int randSpacesPercent, int randLotPercent){
^
ParkingLot.h:28:2: note: candidate expects 6 arguments, 0 provided
ParkingLot.h:7:7: note: ParkingLot::ParkingLot(const ParkingLot&)
class ParkingLot {
^
ParkingLot.h:7:7: note: candidate expects 1 argument, 0 provided
ParkingLot.h:7:7: note: ParkingLot::ParkingLot(ParkingLot&&)
ParkingLot.h:7:7: note: candidate expects 1 argument, 0 provided
Could anyone provide some advice? I have no idea why it would try to construct a ParkingLot object when I only want to construct a Node of type ParkingLot.
Here is the implementation:
#include <iostream>
template <typename T> class Node {
public:
/*Class variables*/
T data;
Node* next;
/*Class constructors*/
Node(T input) {
data = input;
next = NULL;
}
};
template <typename Type> class LinkedList {
public:
/*Class variables*/
Node<Type>* head;
/*Class constructor*/
LinkedList(){
head = NULL;
}
/*Class Methods*/
void addNode(Type value) {
Node<Type>* p;
if (head == NULL) {
head = new Node<Type>(value); ********ERROR
}
else {
p = head;
while (p->next != NULL){
p = p->next;
}
p->next = new Node<Type>(value); ************ERROR
}
}
//Check to see if linked list contains specified value
bool contains(Type value) {
Node<Type>* search;
if ( head != NULL) {
search = head;
}
else {
return false;
}
while(search->next != NULL) {
if (search->data.compare(value)) {
return true;
}
search = search->next;
}
if (search->next == NULL && search->data.compare(value)) {
return true;
}
else {
return false;
}
}
void print(){
Node<Type>* p;
p = head;
while (p != NULL) {
std::cout << p->data.print() << " ";
p = p->next;
}
std::cout << "\n";
}
};
Here is the code from the Decal class which just tries to use a linked list of type parking lot. It is designed in this way so that some amount of parking lots correspond to a type of decal.
#include <string>
#include "ParkingLot.h"
#include "LinkedList.h"
class Decal {
//Class Variables
private:
LinkedList <ParkingLot> decal_list;
std::string decal_name;
//Class Methods
public:
Decal(std::string name) {
decal_name = name;
}
void addLot(ParkingLot newLot) {
decal_list.addNode(newLot);
}
bool hasLot(ParkingLot searchLot) {
return decal_list.contains(searchLot);
}
};
Lastly, I have included the Parking Lot constructor for reference. It has a name and locations x,y as well as other parameters for filling its spaces.
ParkingLot(int num_spaces, std::string name, int x, int y, int randSpacesPercent, int randLotPercent){
//Generate bool array for parking spaces
lot_capacity = num_spaces;
for (int i =0; i<lot_capacity; i++) {
parking_lot[i] = true;
}
/*Determine if lot is full or not, and if not generate random full spaces*/
//Assigning percentages to corresponding variable
sp_generator = randSpacesPercent;
lot_generator = randLotPercent;
//Make lot full or not based on percentage
generateLot(lot_generator);
//If lot is not full, assign certain percentage of spots as full/empty
if (isFull() == false) {
generateSpaces(sp_generator);
}
//Assing other vars
parking_lot_name = name;
x_locat = x;
y_locat = y;
}
Thank you for any help you can provide!
The ctor of Node called the default ctor of type T, and then assign it in the body of ctor. If type T does not have a default ctor, compile will fail.
It's better to use initializer list in constructor instead of assignment, it will call the copy ctor of type T. And it can improve the performance in most cases.
Node(T input) : data(input), next(NULL) {}
BTW: It's better to use const reference for the parameter input, it can avoid once copy.
Node(const T& input) : data(input), next(NULL) {}
I'm trying to teach myself about classes in C++, and I'm running into a bit of a stumbling block, which I can't seem to clear up. I was hoping someone might be able to point me in the correct direction.
I decided to construct a small Tree class, which constructs a new BST. I want to be able to call certain methods on my object like so:
int main() {
Tree<int> tree1;
tree1.insert(5);
int treeMin = tree1.minValue();
int treeMax = tree1.maxValue();
tree1.printTree();
}
Right now, in order to call these functions, I am defining both public and private functions so that you don't call function in a redundant manner. for instance:
(what I'm trying to avoid)
int main() {
Tree<int> tree1;
tree1.insert(tree1, 5);
int treeMin = tree1.minValue(tree1);
int treeMax = tree1.maxValue(tree1);
tree1.printTree(tree1);
}
In order to do avoid having this redundancy, I am defining a public and private version of the same function. In this way, the public functions call their private counterparts.
template<class T>
class Tree {
private:
treeNode<T>* root;
treeNode<T>* newNode(T data);
void insert(treeNode<T>*& root, T data);
int minValue(treeNode<T>*& root);
int maxValue(treeNode<T>*& root);
void printTree(treeNode<T>*& root);
public:
Tree();
~Tree();
void insert(T data);
int minValue();
int maxValue();
void printTree();
};
And then, as an example:
template<class T>
int Tree<T>::minValue() { minValue(root); }
template<class T>
int Tree<T>::minValue(treeNode<T>*& root) {
if (root == NULL) { return 0; }
if (root->left == NULL) { return root->data; }
else { minValue(root->left); }
}
So, my question is:
If I'm writing my functions recursively, I understand that I need to declare a private function that accepts an argument, but is this considered a bad style? Is this sloppy?
Thanks for your help!
The private member functions in your code are only a needless complication. I would just move their code to the public member functions: less code, more clean code, less indirection so more directly grokable code, all nice. For some of them you might support reuse by making them free functions in a details namespace, but I think that would be premature generalization, expending effort on possible reuse that probably won't take place.
Example code at end of answer.
Re another design issue, declaring
int minValue();
int maxValue();
precludes calling these member functions on a const object. Instead do
int minValue() const;
int maxValue() const;
A third issue, it's generally a Really Bad Idea™ to do i/o in a non-i/o class. If you print the tree to standard output, how would you use the class in a GUI program? So, instead of
void printTree();
do e.g.
ostream& operator<<( ostream& stream ) const;
or e.g.
string toString() const;
A fourth issue, you need to take charge of copying – read up on the “rule of three” and the “rule of zero”.
The simplest way to do that is to replace
treeNode<T>* root;
with
unique_ptr< treeNode< T > > root;
where unique_ptr is std::unique_ptr.
Alternatively declare at least a copy constructor and a copy assignment operator, or inherit from a “non-copyable” class. To make the class effectively non-copyable, you can make these operators private or protected. To make it copyable, make them public and do the right thing in each (a good default implementation of the copy assignment operator is to express it in terms of copy construction via the copy-and-swap idiom, which means introducing a non-throwing swap function).
A fifth issue is that the implementation
template<class T>
int Tree<T>::minValue(treeNode<T>*& root) {
if (root == NULL) { return 0; }
if (root->left == NULL) { return root->data; }
else { minValue(root->left); }
}
strongly suggests that each node stores a value that's implicitly convertible to int. You don't provide the declaration of treeNode. But this looks like a design level bug, that the intent was for minValue to return a T, not an int – and ditto for maxValue.
A very small coding issue (not design level): in C++11 and later you should preferentially use nullptr, not NULL.
nullptr can be freely passed through argument forwarding functions, while NULL then suffers a decay to integral type, since NULL is just a zero-constant of integral type.
nullptr does not require that you include any header, while NULL is defined by a header, i.e. with nullptr you avoid a header dependency.
Finally, regarding
if (root == NULL) { return 0; }
for the minValue, this may of course be the intention, the design. But possibly you want to either signal failure or treat the call as a logic error.
To treat the call as an error, assert( root != nullptr ); and provide a means for the client code to check for empty tree.
To signal failure, either return an object with optional value (e.g. like boost::optional or Barton/Nackmann's original Fallible), or throw an exception (the std::runtime_error class is a good general default exception class choice).
It's also possible to combine the two approaches, to provide both, perhaps with names like minValue and minValueOrX.
More generally it's sometimes possible to reserve some special value as a "no such" indicator. E.g. std::numeric_limits<T>::min(). But this makes for brittle code, since such a value can easily occur naturally in the data, and since client code may easily fail to check for the special value.
Example, coded for C++11:
#include <assert.h>
#include <iostream> // std::cout, std::endl
#include <string> // std::string
namespace my {
using std::string;
template<class T>
class Tree
{
private:
struct Node
{
T value;
Node* p_left;
Node* p_right;
auto to_string() const -> string
{
using std::to_string;
string const left = (p_left == nullptr? "" : p_left->to_string());
string const right = (p_right == nullptr? "" : p_right->to_string());
return "(" + left + " " + to_string( value ) + " " + right + ")";
}
~Node() { delete p_left; delete p_right; }
};
Node* root_;
Tree( Tree const& ) = delete;
Tree& operator=( Tree const& ) = delete;
public:
auto is_empty() const -> bool { return (root_ == nullptr); }
void insert( T const data )
{
Node** pp = &root_;
while( *pp != nullptr )
{
auto const p = *pp;
pp = (data < p->value? &p->p_left : &p->p_right);
}
*pp = new Node{ data, nullptr, nullptr };
}
auto minValue() const -> T
{
assert( root_ != nullptr );
Node* p = root_;
while( p->p_left != nullptr ) { p = p->p_left; }
return p->value;
}
auto maxValue() const -> T
{
assert( root_ != nullptr );
Node* p = root_;
while( p->p_right != nullptr ) { p = p->p_right; }
return p->value;
}
auto to_string() const -> string
{
return (root_ == nullptr? "" : root_->to_string());
}
~Tree() { delete root_; }
Tree(): root_( nullptr ) {}
Tree( Tree&& other ): root_( other.root_ ) { other.root_ = nullptr; }
};
} // namespace my
auto main() -> int
{
my::Tree<int> tree;
for( int const x : {5, 3, 4, 2, 7, 6, 1, 8} )
{
tree.insert( x );
}
using std::cout; using std::endl;
cout << tree.to_string() << endl;
cout << "min = " << tree.minValue() << ", max = " << tree.maxValue() << endl;
}
Output:
(((( 1 ) 2 ) 3 ( 4 )) 5 (( 6 ) 7 ( 8 )))
min = 1, max = 8
Suppose I have a C++ class and I would like to have a recursive member-function which is called with instances items of the class, for example
// the eplicit "this" is just for clarity in the following code:
void recursivePrintTree(){
(if this == NULL){ // We are "out" of the tree
return;
}
cout << this->val;
(this->leftSon)->printBinaryTree();
(this->rightSon)->printBinaryTree();
}
The problem is of course invoking undefined behaviour by calling printBinary with NULL in the first place! so I would like to avoid this, and as far as I know I have at least three ways of doing so:
1) Using static member functions, which get an explicit this-type argument that can be safely checked. this is actually what I did so far but because it's a very recursive implementation, almost all of the member-functions get coded as static. That's not very good, right?
2) checking the stop condition for the next node before having another recursive call with a NULL pointer possibly as "this". This is a much less natural form of writing and actually checks other items other that This. and I would like to avoid it.
3) Using default dummy values. Tried it, felt it's not really saving me any special-case-treatment, but that may have been just because of the Generic-ness of my tree.
I have really been fussing around this matter for a while now so would appreciate any good advice.
Your code is wrong.
Instead of checking for NULL in this, you can check for NULL in this->next so you can avoid calling the method for NULL pointers in the first place.
That is, instead of:
void printBinaryTree() {
if(this == NULL){
return;
}
cout << this->val;
this->next->printBinaryTree();
}
Do this:
void printBinaryTree() {
cout << this->val;
if(this->next)
this->next->printBinaryTree();
}
BTW. this is a linked list.
The second solution is the only solution if you want to
navigate from within the node structure. The usual solution,
however, is to distinguish between nodes and the tree, and the
navigation code is a member of the tree object, not the node.
At most, the node has a function to return the next pointer.
This means that the naviagtion functions would take a pointer to
the nodes; your printBinaryTree might be something like:
void
BinaryTree::print( Node const* node )
{
if ( node != NULL ) {
node->print();
print( node->next() );
}
}
Or you can use the visitor pattern, which separates the tree
walking code from the actions at each node.
Let's try out your implementation:
#include <iostream>
class BinaryTree {
public:
BinaryTree(int value, BinaryTree * left, BinaryTree * right) : value_(value), left_(left), right_(right) {}
void printBinaryTree(int depth = 0) {
for ( int i = 0; i < depth; i++ ) std::cout << " ";
if ( this == NULL ) {
std::cout << "Null node, returning..." << std::endl;
return;
}
else {
std::cout << value_ << std::endl;
}
left_->printBinaryTree(depth+1);
right_->printBinaryTree(depth+1);
}
private:
int value_;
BinaryTree * left_;
BinaryTree * right_;
};
int main() {
BinaryTree leaf(0,NULL,NULL);
BinaryTree top(1,&leaf, &leaf);
top.printBinaryTree();
return 0;
}
If we make this run, we get an output that looks like this:
1
0
Null node, returning...
Null node, returning...
0
Null node, returning...
Null node, returning...
The reason why this works is explained here: Accessing class members on a NULL pointer
However, as per C++ standard, doing this is undefined behaviour. As in, this works only because the implementation of your, or in this case mine, compiler is able to make this work. It is not a guarantee of any kind, and this reduces your portability, and could even stop working if you ever need to update your compiler!
There are a bunch of alternatives to this. You already list some, though I must say I dislike the static implementation because it doesn't make really sense from a design standpoint, and makes all your code a mess. An additional solution could be to make the printBinaryTree function virtual, and define the leaf nodes as a child class of the tree. This is an example:
#include <iostream>
class BinaryTree {
public:
BinaryTree(int value, BinaryTree * left, BinaryTree * right) : value_(value), left_(left), right_(right) {}
virtual void printBinaryTree(int depth = 0) {
for ( int i = 0; i < depth; i++ ) std::cout << " ";
std::cout << value_ << std::endl;
left_->printBinaryTree(depth+1);
right_->printBinaryTree(depth+1);
}
int getValue() { return value_; }
private:
int value_;
BinaryTree * left_;
BinaryTree * right_;
};
class BinaryTreeLeaf : public BinaryTree {
public:
BinaryTreeLeaf(int value) : BinaryTree(value, NULL, NULL) {}
virtual void printBinaryTree(int depth=0) {
for ( int i = 0; i < depth; i++ ) std::cout << " ";
std::cout << getValue() << std::endl;
}
};
int main() {
BinaryTreeLeaf leaf(0);
BinaryTree top(1,&leaf, &leaf);
top.printBinaryTree();
return 0;
}
The output here, as desired, is:
1
0
0