So I am creating a Huffman tree, and I am having a hard time overriding a function, and I believe that it is due to a covariance issue. Here is the hierarchy that I am having a hard time with in my code:
class TreeInterface {
public:
TreeInterface() {}
virtual ~TreeInterface() {}
virtual NodeInterface * getRootNode() const = 0;
};
class Tree : TreeInterface
{
public:
Tree()
{}
virtual ~Tree()
{}
Node* getRootNode()
{
return treeRoot;
}
private:
Node* treeRoot;
};
Those work just fine, but its the next block that has issues.
class HuffmanInterface{
public:
HuffmanInterface() {}
virtual ~HuffmanInterface() {}
virtual bool createTree(string filename) = 0;
virtual string encodeMessage(string toEncode) = 0;
virtual TreeInterface * getTree() = 0;
virtual map<char, string> getEncodings() = 0;
};
class Huffman : HuffmanInterface{
public:
Huffman() {}
~Huffman() {}
bool Huffman::createTree(string filename){ }
string Huffman::encodeMessage(string toEncode){ }
string Huffman::decodeMessage(string toDecode){ }
Tree* Huffman::getTree(){ }
map<char, string> Huffman::getEncodings(){ }
So the problem is apparently in the getTree() function, giving the following error
invalid covariant return type for ‘virtual Tree* Huffman::getTree()’:
Tree * getTree();
but as far as I know, Tree* should be a valid covariant of TreeInterface*. replacing Tree* with TreeInterface* makes the program compile, but it's not what I need in my actual program. Any help is greatly appreciated!
class Tree : TreeInterface { ... };
is equivalent to
class Tree : private TreeInterface { ... };
You need to make the inheritance public.
class Tree : public TreeInterface { ... };
Related
I have an abstract base class Node, which is derived from an abstract Interface class IObservable.
There is a several classes implementing the abstract IObservable: SingleObservable and MultiObservable
I want to create a class ObservableNode, derived from the base Node class and specify on its declaration which class to use for the implementation of the IObservable interface.
I've added using ... statements for every pure virtual method in IObservable, referring to the methods in the implementation classes but I still get errors saying that ObservableNode is an abstract class, missing the implementation of notifyObservers(IObject*).
If I add the parameter IObject* to the using statement I get an "expected ';' before '(' token" error
How can I solve this?
class IObservable {
public:
virtual ~IObservable() {};
virtual void notifyObservers(IObject*) = 0;
};
class SingleObservable: public IObservable {
public:
virtual ~SingleObservable() {};
void notifyObservers(IObject*) override {
//some implementaiton
};
};
class MultiObservable: public IObservable {
public:
virtual ~MultiObservable() {};
void notifyObservers(IObject*) override {
//some other implementaiton
};
};
class Node: public IObservable {
public:
virtual ~Node() {};
};
class ObservableNode: public Node, public SingleObservable {
public:
virtual ~ObservableNode() {};
using SingleObservable::notifyObservers;
// using SingleObservable::notifyObservers(IObject*); // expected ';' before '(' token error
};
Node* node = new ObservableNode() // instantiating abstract class error, missing notifyObservers(IObject*) implementation
Your problem seems to be that you inherit Node which is still abstract, and also causes to introduce the good old multimple inheritance vicious diamond problem. When I change your code like this, the error disappears:
class Node: public IObservable {
public:
virtual ~Node() {};
// ** Added an implementation here **
void notifyObservers(IObject*) override {
//some other implementaiton
};
};
class ObservableNode: public virtual Node, public virtual SingleObservable {
// ^^^^^^^ ^^^^^^^
public:
virtual ~ObservableNode() {};
using SingleObservable::notifyObservers;
};
int main() {
Node* node = new ObservableNode();
}
See it live on coliru.
#πάντα ῥεῖ's answer describe one workaround, but possible this is not what OP is after here. Also, as my comment describe under the answer, the approach in the answer might give unexpected results e.g. when invoking node->notifyObservers(obj):
Note that in this particular example, Node* node = new
ObservableNode(); will mean node->notifyObservers(obj) will invoke
Node::notifyObservers(IObject*) and not
SingleObservable::notifyObservers(IObject*), which might be
unexpected, considering we instantiate an ObservableNode object
which specifies using SingleObservable::notifyObservers;.
In OP's original code, we are suffering from multiple inheritance ambiguity, as we are not using virtual inheritance when Node and SingleObservable (and MultiObservable) derives from IObservable:
class SingleObservable: public IObservable {
public:
virtual ~SingleObservable() {};
void notifyObservers(IObject*) override {
//some implementaiton
};
};
class Node: public IObservable {
public:
virtual ~Node() {};
};
Meaning our the object's memory layout, w.r.t. inheritance, of ObservableNode to looks like the following
IObservable IObservable
| |
Node SingleObservable
\ /
ObservableNode
whereas, in this context, we are likely to want an object's memory layout looking as follows
IObservable
/ \
Node SingleObservable
\ /
ObservableNode
If we were to correct this, Node can stay abstract, and a call to node->notifyObservers(obj) with node as OP's example will result in invocation of SingleObservable::notifyObservers, as might have been expected.
class Node: public virtual IObservable {
// ↑↑↑↑↑↑↑
public:
virtual ~Node() {};
};
class SingleObservable: public virtual IObservable {
// ↑↑↑↑↑↑↑
public:
virtual ~SingleObservable() {};
void notifyObservers(IObject*) override {
std::cout << "SingleObservable::notifyObservers";
};
};
struct DummyObj : public IObject {};
int main() {
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
}
Note that we not need virtual inheritance for when ObservableNode derives from Node and SingleObservable.
Finally, if we'd want Node be non-abstract (specifically, to provide an override of void notifyObservers(IObject*)), then ObservableNode must provide it's own (final) override of it, as we will otherwise inherit two final overrides of it in ObservableNode (one from Node and one from SingleObservable). In this case, ObservableNode could simply define its own override which explicitly calls the base class of choice, e.g.
class Node: public virtual IObservable {
public:
virtual ~Node() {};
void notifyObservers(IObject*) override {
std::cout << "Node::notifyObservers";
};
};
class SingleObservable: public virtual IObservable {
public:
virtual ~SingleObservable() {};
void notifyObservers(IObject*) override {
std::cout << "SingleObservable::notifyObservers";
};
};
class ObservableNode: public Node, public SingleObservable {
public:
virtual ~ObservableNode() {};
// Non-ambiguous final override in ObservableNode.
// We could use `override` specifier here, but we might as well
// use `final`, if we are not expecting something to derive from ObservableNode.
void notifyObservers(IObject* obj) final {
SingleObservable::notifyObservers(obj);
};
};
struct DummyObj : public IObject {};
int main() {
Node* node = new ObservableNode();
DummyObj obj;
node->notifyObservers(obj); // SingleObservable::notifyObservers
}
See ISO C++ FAQ - Inheritance — Multiple and Virtual Inheritance for details on the diamond inheritance structure and virtual inheritance.
Thanks for all the suggestions! Implementing those caused a lot of other problems with other classes already using the Observable implementations, so I opted to solve it in a different manner, by including an implementation instance and delegating all methods to that one
class IObject {
public:
virtual ~IObject() {};
};
class IObservable {
public:
virtual ~IObservable() {};
virtual void notifyObservers(IObject*) = 0;
};
class SingleObservable: public IObservable {
public:
virtual ~SingleObservable() {};
void notifyObservers(IObject*) override {
std::cout << "Single\n";
//some implementaiton
};
};
class MultiObservable: public IObservable {
public:
virtual ~MultiObservable() {};
void notifyObservers(IObject*) override {
std::cout << "Multi\n";
//some other implementaiton
};
};
class Node: public IObservable {
public:
virtual ~Node() {};
// void notifyObservers(IObject*) override { };
};
class SingleObservableNode: public Node {
public:
SingleObservableNode() {};
virtual ~SingleObservableNode() {
delete obs;
};
void notifyObservers(IObject* obj) override {
obs->notifyObservers(obj);
}
private:
IObservable* obs = new SingleObservable();
};
class MultiObservableNode: public Node {
public:
MultiObservableNode() {};
virtual ~MultiObservableNode() {
delete obs;
};
void notifyObservers(IObject* obj) override {
obs->notifyObservers(obj);
}
private:
IObservable* obs = new MultiObservable();
};
Node* node1 = new SingleObservableNode();
Node* node2 = new MultiObservableNode();
int main()
{
node1->notifyObservers(nullptr); // "Single"
node2->notifyObservers(nullptr); // "Multi"
return 0;
}
I'm currently creating a basic UI system for a game I'm writing. It's organized as a tree of nodes. I'm trying to write it so that only the root node can call the update method on other nodes. I thought I understood C++ inheritance but it's once again laughing at my incompetence. I've tried to create a bare-bones example below:
class Base
{
public:
virtual ~Base() { }
protected:
virtual void update_internal() = 0;
};
class Node_A : public Base
{
protected:
virtual void update_internal() { std::cout << "Update Node A" << std::endl; }
};
class Node_B : public Base
{
protected:
virtual void update_internal() { std::cout << "Update Node B" << std::endl; }
};
class Root : public Base
{
public:
void add_node (Base* node) { m_nodes.push_back(node); }
void update()
{
for (auto& node : m_nodes)
{
node->update_internal();
}
}
protected:
std::vector<Base*> m_nodes;
virtual void update_internal() { }
};
int main()
{
Node_A alpha_node;
Node_B beta_node;
Root root_node;
root_node.add_node(&alpha_node);
root_node.add_node(&beta_node);
root_node.update();
}
When I try to compile this GCC gives me the error:
error: 'virtual void Base::update_internal()' is protected
All of the nodes including root inherit the update_internal() method from Base, I don't understand why it matters that it is protected. I thought it was only private members and methods that derived classes couldn't access.
You can only call a protected/private function of a base class only from an instance of the derived class (unless of course you use friends). So the derived class can only access the private/protected members of its base part, not of some other base. In your case, you call it via a reference to a Base* in
for(auto& node : m_nodes)
node->update_internal();
so the compiler complains.
Just befriend Base and Root;
class Base
{
friend class Root; // <- yes,this
public:
virtual ~Base() { }
protected:
virtual void update_internal() = 0;
};
This is a stock example for the Template Method pattern.
The public method of the Root class exposes, what's needed to be implemented internally.
class Base
{
protected:
virtual void update_internal() = 0;
static void DoUpdate( Base *node )
{
node->update_internal();
}
};
class Root : public Base
{
public:
void update()
{
for (auto node : m_nodes)
{
Base::DoUpdate( node );
}
}
protected:
virtual void update_internal() override {}
std::vector<Base*> m_nodes;
};
I have this tree with different types of nodes that I need to do a deep copy on. The hierarchy looks something like this:
class AllNodes
{
//this is a purely virtual base class
};
class TreeNode : public AllNodes
{
AllNodes *rChild, *lChild;
};
class LeefNode : public AllNodes
{
int value;
};
The problem is that when I want to do a deep copy of the entire tree, I don't know what nodes will have children and what nodes will have values. I've tried this, but it wont work (for obvious reasons):
void AllNodes::deepCopy(AllNodes* &copied, AllNodes* o)
{
if(o->rChild == nullptr)
copied->rChild = nullptr;
else
{
copied->rChild = o->rChild;
deepCopy(copied->rchild, o->rChild);
}
if(o->lChild == nullptr)
copied->lChild = nullptr;
else
{
copied->lChild = o->lChild;
deepCopy(copied->lChild, o->lChild);
}
}
Does anyone have some ideas of how to accomplish this?
Create a virtual method and implement it in TreeNode and LeafNode.
class AllNodes
{
//this is a purely virtual base class
virtual AllNodes* copy() const = 0;
};
class TreeNode : public AllNodes
{
AllNodes* rChild, lChild;
virtual AllNodes* copy() const {
TreeNode *n = new TreeNode;
n->rChild = rChild->copy();
n->lChild = lChild->copy();
return n;
}
};
class LeafNode : public AllNodes
{
int value;
virtual AllNodes* copy() const {
LeafNode *n = new LeafNode;
n->value = value;
return n;
}
};
(Just a draft)
This is polymorphic behavior (creating a deep copy, based on the concrete type of the object). As such, it should be implemented in a virtual function, accross the entire nodes hierarchy.
The function to perform the deep copy is usually called clone:
class AllNodes
{
//this is a purely virtual base class
public:
virtual AllNodes* clone() = 0;
};
class TreeNode : public AllNodes
{
AllNodes *rChild, *lChild; // you skipped declaring lChild as a pointer
public:
virtual AllNodes* clone() override // recursive implementation for child nodes
{
return new TreeNode{
rChild ? rChild->clone() : nullptr,
lChild ? lChild->clone() : nullptr }; // assume existence of this
// constructor
}
};
class LeafNode : public AllNodes
{
int value;
public:
virtual AllNodes* clone() override
{
return new LeafNode{ value }; // assume existence of this constructor
}
};
Client code (deep copy of the entire tree):
AllNodes *original; // filled in elsewhere
AllNodes *deepCopy = original->clone();
I'm very new to C++ and I'm not quite sure how to override methods from base class.
I apologize for not translating the code to English prior to posting, but I don't think it would make any difference.
A summary of what I'd like to do is create an abstract base class for linked lists, then derive singly/doubly/multiply linked/circular lists from it etc.
Here is the code:
#ifndef __LISTA_H__
#define __LISTA_H__
class Elem;
class JulElem;
class Lista // Abstract list class
{
public:
Lista();
~Lista();
virtual void dohvatiGlavu() = 0;
virtual void dodajNaKraj(int vred) = 0;
virtual void dodajIza(Elem* elem, int vr) = 0;
virtual void obrisiIza(Elem* elem) = 0;
virtual bool prazna() = 0;
virtual int velicina() = 0;
protected:
class Elem
{
protected:
int vred;
};
virtual Elem* noviElem();
private:
Elem* glava;
};
class Jul : Lista // Singly linked list
{
public:
void dohvatiGlavu();
void dodajNaKraj(int vred);
void dodajIza(Elem* elem, int vr);
void obrisiIza(Elem* elem);
bool prazna();
int velicina();
private:
class JulElem : Elem
{
};
JulElem* noviElem();
};
This is the error I get:
error C2555: 'Jul::noviElem': overriding virtual function return type differs and is not covariant from 'Lista::noviElem'
I've mostly seen people use structs for list elements but I'm not sure how that would fit my case scenario because different types of lists require different types of structs.
Thanks
The problem is that the inheritance is private, so JulElem* is not covariant with Elem*. Use public inheritance:
class JulElem : public Elem
^^^^^^
The return type of the function can not be overrided. you should do like this:
in the base, define the function as:
virtual void noviElem(Elem** result);
The parameter "result" served as an output paramter
It seems like you need to use templates.
Here is an example :
template<class T>
T Add(T n1, T n2)
{
T result;
result = n1 + n2;
return result;
}
I am stuck with a code duplication issue, regarding the visitor pattern for a tree. The current situation is as follows: I have a tree, consisting of two different node classes, i.e. leafs and non-leafs. In addition I have two visitor base classes that look very alike except that one visits const trees and the other non-const trees. The actual actions the concrete visitors have to do are independent of the node's concrete types. I'll give a short example:
class Visitor;
class ConstVisitor;
class Node {
public:
virtual void accept(Visitor&) = 0;
virtual void accept(ConstVisitor&) const = 0;
};
class Leaf : public Node {
virtual void accept(Visitor& v) {v.visitLeaf(*this);}
virtual void accept(ConstVisitor& cv) {cv.visitLeaf(*this);}
};
class CompoundNode : public Node {
public:
vector<Node*> getChildren() const;
virtual void accept(Visitor& v) {v.visitCompoundNode(*this);}
virtual void accept(ConstVisitor& cv) {cv.visitCompoundNode(*this);}
};
class Visitor {
protected:
virtual void processNode(Node& node) = 0;
public:
void visitLeaf(Leaf& leaf) {
processNode(leaf);
}
void visitCompoundNode(CompoundNode& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children)
child->accept(this);
}
};
class ConstVisitor {
protected:
virtual void processNode(Node const& node) = 0;
public:
void visitLeaf(Leaf const& leaf) {
processNode(leaf);
}
void visitCompoundNode(CompoundNode const& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children)
child->accept(this);
}
};
Concrete visitor classes inherit either from Visitor or from ConstVisitor, depending on whether their processNode method has to alter the nodes visited or not.
You see, there is lots of code duplication between the two visitors, and since I will have to implement another traversal strategy, also for both const and nonconst nodes, I want to avoid that duplication. Are there any possibilities to extract the duplicate code, preferably without using const_cast all over the place?
You could define a TVisitor class template as done below:
#include <type_traits>
class Node;
class CompoundNode;
class Leaf;
template<bool isNonConstVisitor>
class TVisitor
{
typedef typename std::conditional<isNonConstVisitor,
Node, Node const>::type node_type;
typedef typename std::conditional<isNonConstVisitor,
CompoundNode, CompoundNode const>::type compound_node_type;
typedef typename std::conditional<isNonConstVisitor,
Leaf, Leaf const>::type leaf_node_type;
protected:
virtual void processNode(node_type& node) = 0;
public:
void visitLeaf(leaf_node_type& leaf) { processNode(leaf); }
void visitCompoundNode(compound_node_type& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children) { child->accept(*this); }
}
};
And then use Visitor and ConstVisitor as type aliases for corresponding instantiations of that class template:
typedef TVisitor<true> Visitor;
typedef TVisitor<false> ConstVisitor;
You could use templates:
template<typename NodeType,
typename CompoundNodeType,
typename LeafType>
class BaseVisitor {
protected:
virtual void processNode(NodeType& node) = 0;
public:
void visitLeaf(LeafType& leaf) {
processNode(leaf);
}
void visitCompoundNode(CompoundNodeType& cNode) {
processNode(cNode);
auto children = cNode.getChildren();
for (auto child : children)
child->accept(this);
}
};
class Visitor: public BaseVisitor<Node, CompoundNode, Leaf> {
};
class ConstVisitor: public BaseVisitor<const Node, const CompoundNode, const Leaf> {
};