I'm coding my own Tree data structure.
In my parent() function, I want to throw no_parent exception that I created. All functions are implemented in Tree.cpp file.
Tree.hpp
#ifndef Tree_hpp
#define Tree_hpp
#include <stdio.h>
#include <vector>
using namespace std;
template<typename T>
class Tree{
class Node;
class no_parent : public std::exception {
virtual const char* what() const _NOEXCEPT
{
return "no_parent";
}
};
protected:
Node* rootNode;
Node* currentNode;
int _size;
public:
Tree();
void addChild(T* childElem);
void removeChild(int index) throw (out_of_range);
bool empty();
int size();
Tree& root();
bool isRoot();
bool isExternal();
Tree& parent() throw(no_parent);
Tree& child(int index) throw(out_of_range);
int getChildrenNum();
int getChildrenNum(Node* node);
};
#endif /* Tree_hpp */
But when I implement no_parent in Tree.cpp file in this way
template<typename T>
class Tree<T>::no_parent : public std::exception {
virtual const char* what() const _NOEXCEPT
{
return "no_parent";
}
};
I get error message from parent() function "Incomplete type 'Tree::no_parent' is not allowed in exception specification".
How can I implement the no_parent outside of Tree.hpp file??
You cannot implement methods depending on template parameters in a source file which is never included where an instance of the class is needed. You either have to include the source file as well or implement your methods in the header right away. See this question for details.
I hope your business need you to have nested class and a forward declaration in class Tree. I do not care them much.
But your code works fine with "noexcept" keyword from C++11.
http://en.cppreference.com/w/cpp/language/noexcept
I guess the "_NOEXCEPT" does not exist any more. May be in very specific compilers to maintain backward compatibility.
I did few changes to your code and tested, works fine. please find details below.
Removed "stdio" and replaced "iostream", to deal with only C++ (at least the question tag says)
Commented few functions, which are lack of variable declaration.
Here is the code. try it.
#include <iostream>
using namespace std;
template<typename T>
class Tree{
class Node;
class no_parent : public std::exception {
//Added "noexcept" key word here.
virtual const char* what() const noexcept
{
return "no_parent";
}
};
protected:
Node* rootNode;
Node* currentNode;
int _size;
public:
Tree();
void addChild(T* childElem);
// void removeChild(int index) throw (out_of_range);
bool empty();
int size();
Tree& root();
bool isRoot();
bool isExternal();
Tree& parent() throw(no_parent);
//Tree& child(int index) throw(out_of_range);
int getChildrenNum();
int getChildrenNum(Node* node);
};
int main()
{
return 0;
}
Related
KSetBase.h base class , an interface
#ifndef HW6_GTUSETBASE_H
#define HW6_GTUSETBASE_H
class KSet;
#include <cstddef>
namespace TU {
template<typename T>
class KSetBase {
public:
virtual bool empty() const = 0;
virtual size_t size() const = 0; //int is not okay since unsigned also could be in.
//comparisons would be not working if that was case
//detailed
//https://stackoverflow.com/questions/1181079/stringsize-type-instead-of-int
virtual size_t max_size() const = 0;
virtual void insert(T first, T second) = 0; //cift dondurmesi gerekli
virtual void erase(T deleter) = 0;
virtual void clear() = 0;
virtual T find(T deneme) = 0;
virtual size_t count(T testle) = 0;
virtual T begin() = 0;
virtual T end() = 0;
protected:
~GTUSetBase() {
//do nothing
}
};
}
#endif //HW6_GTUSETBASE_H
KSet.h (derived class)
#include "KSetBase.h"
#ifndef HW6_GTUSET_H
#define HW6_GTUSET_H
#include <memory>
using namespace std;
namespace TU {
template<typename T>
class KSet : public KSetBase {
public:
bool empty() const;
size_t size() const;
size_t max_size() const;
void insert(T first);
void erase(T deleter);
void clear();
T find(T deneme);
size_t count(T testle);
T begin();
T end();
protected:
int hmany = 0;
shared_ptr<T> set_harmony;
};
}
#endif //HW6_GTUSET_H
I cant figure out what part of my code is wrong. I basically made a basic inheritance from interface class, which i implemented all functions in KSet.cpp. In theory nothing looks wrong but it gives 2 errors.
both in main.cpp and KSet.cpp
class KSet : public KSetBase {
Error line is this.
I checked #ifndef and #defines, i thought about using forward declaration but i cant seems to work that out.I am really stuck with this problem. I searched whole web about it , in the end there's always a big error on syntax or something that is visible , but i can't figure out on mine. It's very short and simple code.
KSetBase is a template class, if you inherit from it you must specify a template argument:
template<typename T>
class KSet : public KSetBase<T>
In addition, it seems you have a typo in the base class destructor.
I have this code for a Node based Queue implementation and I'm supposed to extends an abstract class called QueueInterface.
template<typename T>
struct QueueInterface {
public:
virtual ~QueueInterface(){};
virtual bool isEmpty() const = 0;
virtual void enqueue(const T value) = 0;
virtual void dequeue() throw(PreconditionViolationException) = 0;
virtual T peekFront() const throw(PreconditionViolationException) = 0;
};
template<typename T>
struct Queue : QueueInterface {
Queue();
~Queue();
bool isEmpty() const;
void enqueue(const T value);
void dequeue() throw(PreconditionViolationException);
T peekFront() const throw(PreconditionViolationException);
private:
Node<T>* front;
Node<T>* back;
};
I keep getting a expected class name before '{' token error even though I included the QueueInterface header file. Why is this happening?
QueueInterface is not a class. You can inherit from something that is not a struct or a class. This thing is what is called a templated class. You can recognize templates with the template<...> just before the templated class. You must specify a type so the compiler can create a class of that type.
In your case, you are trying to create a struct that is also a template. By looking at the overrides of the methods of your base classes, I guess you are trying to do this:
template<typename T>
struct Queue : QueueInterface<T> {
// notice that there ---^--- you are sending the required parameter
// defaulted members are good.
Queue() = default;
// override too.
bool isEmpty() const override;
void enqueue(const T value) override;
void dequeue() throw(PreconditionViolationException) override;
T peekFront() const throw(PreconditionViolationException) override;
private:
Node<T>* front;
Node<T>* back;
};
I'm having some problems implementing a class based on a abstract parent class. It's saying PolishStack is an abstract class, even though all virtual functions are coded:
In file included from braincalc.cpp:10:
./polstack.h:15:7: error: explicit specialization of non-template class 'PolishStack'
class PolishStack<T> : public AbstractStack<T> {
^ ~~~
braincalc.cpp:13:21: error: variable type 'PolishStack<char>' is an abstract class
PolishStack <char> stk;
^
./abstractstack.h:53:16: note: unimplemented pure virtual method 'isEmpty' in
'PolishStack'
virtual bool isEmpty() const = 0;
Here's my class header:
#ifndef POLSTACK_H
#define POLSTACK_H
#include <iostream>
using namespace std;
#include "abstractstack.h"
template <typename T>
class PolishStack<T> : public AbstractStack<T> {
T* data;
int mMax;
int mTop;
public:
PolishStack();
bool isEmpty();
const T& top() const throw (Oops);
void push(const T& x);
void pop();
void clear();
//my funcs:
void printStack();
~PolishStack();
};
#endif
I don't want to give all my code away due to other students cheating, so I'll post the function that the error is complaining about:
#include "polstack.h"
//...
template <typename T>
bool PolishStack<T>::isEmpty() {
if(mTop == 0)
return true;
return false;
}
//...
As others have stated it should be:
template<typename T>
class PolishStack : public AbstractStack<T>
./abstractstack.h:53:16: note: unimplemented pure virtual method 'isEmpty' in
'PolishStack'
virtual bool isEmpty() const = 0;
You're missing the const:
template<typename T>
bool PolishStack<T>::isEmpty() const
// ^^^^^
{
if(mTop == 0)
return true;
return false;
}
Note: You should use the override keyword to be informed when you try to override a function using a different signature (i.e., you're introducing a new function overload instead of overriding the virtual one).
template<typename T>
class PolishStack : public AbstractStack<T>
{
public:
...
bool isEmpty() const override;
...
};
It's hard to tell without all the code, but one thing I noticed is that this:
class PolishStack<T> : public AbstractStack<T> {
should be just:
class PolishStack : public AbstractStack<T> {
That'll fix the first error for sure and potentially (but maybe not) the second.
Try changing to
template <typename T>
class PolishStack : public AbstractStack<T>
As a side note: Exception specifiers throw (Oops) are deprecated.
I was just wondering if there was a way to create a c wrapper API for a c++ class that has inheritance.
Consider the following:
class sampleClass1 : public sampleClass{
public:
int get() { return this.data *2; };
void set(int data);
}
class sampleClass : public sample{
public:
int get() { return this.data; }
void set(int data) {this.data = data; }
}
class sample {
public:
virtual int get();
virtual void set(int data);
private:
int data;
}
How would I wrap the sampleClass1 to make it work in a c context ???
thanks,
First, your sample should really get a proper virtual dtor.
Next, just add one free function with C-binding for each function which is part of the interface, simply delegating:
"sample.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct sample sample;
sample* sample_create();
sample* sample_create0();
sample* sample_create1();
void sample_destroy(sample*);
int sample_get(sample*);
void sample_set(sample*, int);
#ifdef __cplusplus
}
#endif
"sample-c.cpp"
#include "sample.h" // Included first to find errors
#include "sample.hpp" // complete the types and get the public interface
sample* sample_create() {return new sample;}
sample* sample_create0() {return new sampleClass;}
sample* sample_create1() {return new sampleClass1;}
void sample_destroy(sample* p) {delete p;}
int sample_get(sample* p) {return p->get();}
void sample_set(sample* p, int x) {p->set(x);
"sample.hpp"
// Your C++ header here, with class definition
"sample.cpp"
#include "sample.hpp" // Included first to find errors
// Implement the class here
As a requirement of an assignment for a data structures class, I have to get the following class hierarchy to work: http://www.brpreiss.com/books/opus4/
The source code is also provided, and right now I am simply trying to get stuff to compile. This has required re-organizing class definitions into their respective header files, moving template implementation into .inc files, and finishing bits of code which were not implemented. I have been making progress, but I am stuck on the following error (compiled with VC++):
1>main.obj : error LNK2019: unresolved external symbol "public: virtual __thiscall Iterator::~Iterator(void)" (??1Iterator##UAE#XZ) referenced in function "public: virtual __thiscall NullIterator::~NullIterator(void)" (??1NullIterator##UAE#XZ)
I have tried all of the usual solutions (eliminating redundant include statements, cleaning the project and recompiling, etc.) and am not sure where to go. As was previously discussed, the consensus here seems to be that this code-base is really poorly designed. Nonetheless, the requirement of this assignment is to get this code working, and I am into deep to scrap it all together and start from scratch. If it
Here is the iterator class definition in iterator.h
#ifndef ITERATOR_H
#define ITERATOR_H
#include "object.h"
class Iterator
{
public:
virtual ~Iterator ();
virtual void Reset () = 0;
virtual bool IsDone () const = 0;
virtual Object& operator * () const = 0;
virtual void operator ++ () = 0;
};
class NullIterator : public Iterator
{
public:
NullIterator () {}
void Reset () {}
bool IsDone () const { return true; }
Object& operator * () const { return NullObject::Instance(); }
void operator ++ () {}
};
#endif
These are all of the other header files which are associated with iterator:
#ifndef CONTAINER_H
#define CONTAINER_H
#include "object.h"
#include "visitor.h"
#include "iterator.h"
#include "ownership.h"
class Container : public virtual Object, public virtual Ownership
{
protected:
unsigned int count;
Container () : count(0) {}
public:
virtual unsigned int Count () const { return count; }
virtual bool IsEmpty () const { return Count () == 0; }
virtual bool IsFull () const { return false; }
//virtual HashValue Hash () const;
virtual void Put (ostream&) const;
virtual Iterator& NewIterator () const { return *new NullIterator (); }
virtual void Purge () = 0;
virtual void Accept (Visitor&) const = 0;
};
#endif
Stack and Queue also inherit from Container, but it appears only stack makes use of Iterator:
#ifndef STACK_H
#define STACK_H
#include "linkList.h"
#include "container.h"
class Stack : public virtual Container
{
public:
virtual Object& Top () const = 0;
virtual void Push (Object&) = 0;
virtual Object& Pop () = 0;
};
class StackAsLinkedList : public Stack
{
LinkedList<Object*> list;
class Iter;
public:
StackAsLinkedList () : list() {}
~StackAsLinkedList() { Purge(); }
//
// Push, Pop and Top
//
void Push(Object& object);
Object& Pop() override;
Object& Top() const override;
int CompareTo(Object const& obj) const;
//
// purge elements from, and accept elements onto, the list
//
void Purge();
void Accept (Visitor&) const;
friend class Iter;
};
class StackAsLinkedList::Iter : public Iterator
{
StackAsLinkedList const& stack;
ListElement<Object*> const* position;
public:
Iter (StackAsLinkedList const& _stack) : stack(_stack) { Reset(); }
//
// determine whether iterator is pointing at null
//
bool IsDone() const { return position == 0; }
//
// overloaded dereference and increment operator
//
Object& operator*() const;
void operator++();
void Reset() { position = stack.list.Head(); }
};
#endif
If anyone has some insight, it would be much appreciated. I have been trying to solve this one error for the last few hours and haven't made any progress!
The error is a linking error which tells you that you have not provided a definition for the destructor:
virtual ~Iterator();
Which is being called through:
NullIterator::~NullIterator(void)
because NullIterator derives from Iterator class.
Solution is You should provide the definition for the Base class destructor.