I am trying to implement a list data structure in C++.
I want to define a list interface which would be later inherited by implementation such as ArrayList or LinkedList.
I'd like to be able to use it like
List<int>* testList = new LinkedList<int>;
So i've tried to implement full virtual templated class but then realized i cannot mix virtual and templated methods. I tried much different ways and im encountering problems all the way.
Whats the best way to do it ?
Edit (problematic code). I'm trying to make interface to look like this:
template<typename T>
class List {
public:
virtual void add(T*) {};
virtual void remove(unsigned int) = 0;
virtual unsigned int size() = 0;
virtual void get(unsigned int) = 0;
virtual ~List();
};
and then im trying to implement it here:
template<typename T>
class LinkedList : public List<T> {
/* some stuff */
public:
LinkedList();
virtual unsigned int size();
virtual void add(T*); // the problem i guess
virtual void remove(unsigned int);
virtual void get(unsigned int);
virtual ~LinkedList();
};
So i've tried to implement full virtual templated class but then
realized i cannot mix virtual and templated methods.
Your example code indicates, that you don't want virtual, templated methods, but a template class that has virtual methods. The former is not allowed, the latter IS (this is a common point of confusion).
So this is perfectly valid code:
#include <iostream>
#include <memory>
template<class T>
class List{
public:
virtual void push()=0;
virtual void pop()=0;
virtual ~List()=default;
};
template<class T>
class LinkedList: public List<T>{
public:
virtual void push() {
std::cout << "Pushed element to Linked List"<< std::endl;
}
virtual void pop() {
std::cout << "Poped element from Linked List"<< std::endl;
}
};
template<class T>
class ArrayList: public List<T>{
public:
virtual void push() {
std::cout << "Pushed element to ArrayList"<< std::endl;
}
virtual void pop() {
std::cout << "Poped element from ArrayList"<< std::endl;
}
};
int main()
{
List<int>* list1=new LinkedList<int>();
List<int>* list2=new ArrayList<int>();
// And this is how you would actually create objects on the heap nower days:
std::unique_ptr<List<int>> list3=std::make_unique<LinkedList<int>>();
list1->push();
list2->push();
list3->push();
list1->pop();
list2->pop();
list3->pop();
delete(list1);
delete(list2);
//no delete(list3) needed
return 0;
}
Besides that, I don't know, why you want to do that. C++ has a perfectly fine implementation of a linked list and an implementation of and array/vector and thanks to iterator based semantic, you can run (almost) any algorithm on them without the need for a common base class.
I apologize, if this sounds harsh, but it looks like you are comming from Java and trying to learn C++. But instead of learning C++, you try to write wrappers, that make C++ look like java. While this is certainly possible most of the time (as long as you don't forget, that standard c++ doesn't have a garbage collector) its often not a sensible approach. whether that holds true in your case of course depends on your application. But my recommendation ist to learn about iterators and the standard library algorithms.
Related
I'm trying to implement a strategy pattern. Right now I'm making a vector of function pointers that take in a vector of ints as their type. I called this vector of function pointers "algo". I want each of the function pointers in the vector to point to a different sorting class (merge, bubble, or insertion). My class structure looks like this: Algorithm is the base class, Sort is an abstract class that inherits from Algorithm, and then Merger, Insertion, and Bubble all inherit from Sort. The problem that I'm running into right now is I can't seem to get my mergePointer pointed to the sortFunc() inside the Merger class. When I try to execute my code it says:
main.cpp:59:28: error: use of undeclared identifier 'sortFunc'
mergePointer = sortFunc();
^
I originally figured the problem was scope resolution so I added Merger:: infront of sortFunc() and I got the same error. I'm not to familiar with polymorphism and am not even sure if what I'm trying to do is possible, any thoughts?
class Algorithm{
private:
public:
vector<int> data;
static std::vector<void (*)(std::vector<int>&)> algo;
void (*activeAlgo)(std::vector<int>&);
enum SortingAlgorithms{
Merge = 0, Insertion, Bubble, Last
};
void load(){
void (*mergePointer)(vector<int>&);
mergePointer = sortFunc();
algo.push_back(mergePointer);
}
void select(SortingAlgorithms sort){
}
};
//abstracted class
class Sort: public Algorithm{
private:
public:
virtual void sortFunc() = 0; //pure virtual function
};
class Merger: public Sort{
private:
public:
void sortFunc(){
data = mergeSort(data);
print(data);
}
};
class Insertion: public Sort{
private:
public:
void sortFunc(){
printVec(data);
insertionSort(data);
printVec(data);
}
};
class Bubble: public Sort{
private:
public:
void sortFunc(){
printVector(data);
bubbleSort(data);
printVector(data);
}
};
int main(){
Sort *myAlgo;
myAlgo->select(Algorithm::Bubble);
}
Note that void(*)(std::vector<int>&) can point only to a namespace function or to static member. Pointers to members are class-specific and have to be called with special operator .* or ->*. What you may implement, is a CRTP with virtual base class (stripped of static vector and other bells and whistles for brevity):
#include <iostream>
#include <cstdlib>
class ActorBase
{
public:
// virtual interfaces
virtual void action() = 0;
};
template <class T>
class Actor : public ActorBase
{
protected:
typedef void(T::* FuncPtr)(/* params */);
FuncPtr algo;
public:
void action()
{
/* do call algo for appropriate object by treating this as pointer to T */
(dynamic_cast<T*>(this)->*algo)(/* args */);
}
};
class Concrete : public Actor<Concrete>
{
void bar() { std::cout << "Hello, Concrete!" << std::endl; }
public:
Concrete() { algo = &Concrete::bar; }
};
int main()
{
Concrete a;
a.action();
return EXIT_SUCCESS;
}
Curiously Recurrent Template Actor is very special template which can cast pointer to self to derived class. Still, it can't know anything about Concrete, e.g. typedefs or members. If it required to pass some traits like that, Actor Should be derived from a template class specialized for concrete T, known as trait class.
Not sure that this perverted approach is what actually needed to solve your X problem though, but at least it's syntactically correct. Here is a canonical CRTP.
Note that the call by member pointer requires .* \ -> AND parenthesis, because call operator () got higher priority than .*.
Hello I'm studying c++ language and I'm really wondering that if use object Pointer with dynamic array. Weapon class is derived by CItem class. At this time I'm typing like this.
CItem* pItem = new cWeapon[m_size];
and I doing initialize each object like this
pItem[0].initialize();
pItem[1].initialize();
pItem[2].initialize();
pItem[3].initialize();
....
pItem[n].initialize();
However this time make problem. Size is different pItem and cWeapon. Because Pointer Operation cause error.
and I wondering that how solve this problem?
sorry about my fool English skill.
Example code:
#include <iostream>
#include <memory>
#include <vector>
class BaseItem // abstract class
{
public:
virtual void initialize() = 0; // pure virtual function (no implementation)
};
class Sword : public BaseItem
{
public:
void initialize() override
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
class Shield : public BaseItem
{
public:
void initialize() override
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
int main()
{
std::vector<std::unique_ptr<BaseItem>> items;
items.emplace_back(new Sword);
items.emplace_back(new Sword);
items.emplace_back(new Shield);
items.emplace_back(new Sword);
items.emplace_back(new Shield);
for(auto& element : items)
{
element->initialize();
}
return 0;
}
You can run it here: wandbox.org
Output:
virtual void Sword::initialize()
virtual void Sword::initialize()
virtual void Shield::initialize()
virtual void Sword::initialize()
virtual void Shield::initialize()
In this implementation I used std::vector for dynamic arrays. Vector is containing types of smart pointer to BaseItem. In this case smart pointer is std::unique_ptr it helps a lot with resource management and it is easy to use. Without it you need manually delete all elements from vector. I really recomend using it.
Our BaseItem now can provide "interface" that we want to implement in any other class. If you don't want to force class to implement such method just don't make it pure virtual (remove = 0 and add {} body of function)
More information about:
C++ Abstract Class
__PRETTY_FUNCTION__
C++ virtual functions
C++ inheritance
This is kind of "old" approach. You can read also about composition and entity system (ES).
Scenario (see code below for reference):
The original (Base) implementation must have func1() returning a list. Internally it makes calls to merge and splice.
The subsequent (Derived) implementation must have func1() returning a vector. It needs random access.
func2() is common to both implementations and simply needs a forward iterator.
#include <iostream>
#include <list>
#include <vector>
class Base {
protected:
virtual void func1(std::list<int>& l /* out parameter */) {
// This must use list. Calls merge and splice.
std::cout << "list version of func1 in base\n";
}
virtual void func1(std::vector<int>& v) {
// This should never be called, but code won't compile without it.
std::cout << "vector version of func1 in base\n";
}
template <class T> void func2(T container) {
typename T::const_iterator it = container.cbegin();
// Iterate and perform work. Common to both Base and Derived.
std::cout << "func2 in base\n";
}
template <class T> void processHelper() {
T container;
func1(container);
func2<T>(container);
}
public:
virtual void process() {
processHelper<std::list<int> >();
}
};
class Derived : public Base {
protected:
virtual void func1(std::vector<int>& v /* out parameter */) {
// This must use a random access container.
std::cout << "Vector version of func1 in derived\n";
}
public:
virtual void process() {
processHelper<std::vector<int> >();
}
};
int main(int argc, const char * argv[])
{
std::vector<int> var;
Derived der;
der.process();
//std::list<int> var;
//Base bs;
//bs.process();
std::cout << "done\n";
}
Goals:
No (or minimal) duplication (cut and paste) of code.
Avoid compiling with Boost. (Haven't needed it yet. Don't want to for this.) This rules out a couple of any_iterator implementations.
Question:
Is there a better OO design in C++ to achieve what I am doing? I have reasons for not wanting to turn my list into a vector or vice versa before returning from func1(). Specifically, the list is large at this point and I'd prefer to not incur the extra copy. I could have designed the func1()'s to return an opaque_iterator http://www.mr-edd.co.uk/code/opqit but was hesitant to bring in an unknown header file.
In any case, the question took on an academic life of it's own. This problem is so easy in Java since the collections implement common interfaces, but seems challenging in C++. Particularly bothered by the ugliness of having to implement Base::func1(std::vector& v) just to get the code to compile even though there's no execution path that will ever call this function. Hoping there's an easier way and I'm just not seeing a more straightforward solution.
The C++ way is working with iterators. You can do pretty much anything with the standard algorithms. The library is on intentionally separated on
Containers <--> Iterators <--> Algorithms
Containers define iterators (that are basically glorified pointers) and algorithms work with iterators. Containers and algorithms are unkown to each other.
Normally you would pass a couple of iterators (usually container.begin() and container.end()) and the algorithm will be implemented in terms of those.
Have a look at the standard algorithms and see if you can come up with a solution on what you want to do. To do that your function should be templated on iterators rather than on containers.
Hope that helps.
The generic way would be to have func1 take an output iterator:
template<class OutputIterator> void func1(OutputIterator &&out) {
:
You then call it with a back_insert_iterator on the container you want to use for output:
std::list<int> tmp;
obj->func1(std::back_inserter(tmp));
I ended up finding lots of questions along the same lines, some on Stack Overflow. So maybe this is a duplicate. If so, apologies. Here are some relevant links:
How to write a function that takes an iterator or collection in a generic way?
Generic iterator
http://www.artima.com/cppsource/type_erasure.html
I ended up going with a simple type erasure approach modeled after this article: http://www.cplusplus.com/articles/oz18T05o/ I can't claim to understand everything that's going on here, but it does work. The only downside is that I had to wrap the iterator API in my Container class and return all primitives and well-known classes rather than just expose the underlying iterator directly. So my Container wrapper is not very reusable.
I have posted the code I wrote below in the hope that it will be useful to someone else:
#include <iostream>
#include <list>
#include <vector>
// Type erasure for returning different std containers based off of: http://www.cplusplus.com/articles/oz18T05o/
class Container {
protected:
class IContainer {
public:
virtual ~IContainer() {}
virtual void setBegin() = 0;
virtual bool isEnd() = 0;
virtual int get() = 0;
virtual void next() = 0;
};
template <typename T> class ContainerModel : public IContainer {
public:
ContainerModel(const T& container_) : m_container(container_) {}
virtual ~ContainerModel() {}
virtual void setBegin() {
m_cit = m_container.cbegin();
}
virtual bool isEnd() {
return (m_cit == m_container.cend());
}
virtual int get() {
return *m_cit;
}
virtual void next() {
++m_cit;
}
protected:
T m_container;
typename T::const_iterator m_cit;
};
std::shared_ptr<IContainer> m_spContainer;
public:
template <typename T> Container(const T& t_) : m_spContainer(new ContainerModel<T>(t_)) {}
virtual ~Container() {}
virtual void setBegin() {
m_spContainer->setBegin();
}
virtual bool isEnd() {
return m_spContainer->isEnd();
}
virtual int get() {
return m_spContainer->get();
}
virtual void next() {
m_spContainer->next();
}
};
class Base {
protected:
virtual Container func1() {
std::cout << "list version of func1 in base\n";
std::list<int> l;
// Do lots of stuff with lists. merge(), splice(), etc.
return Container(l);
}
virtual void func2(const Container& container) {
// Iterate using setBegin(), get(), next() and isEnd() functions.
std::cout << "func2 in base\n";
}
public:
virtual void process() {
Container container = func1();
func2(container);
}
};
class Derived : public Base {
protected:
virtual Container func1() {
std::cout << "Vector version of func1 in derived\n";
std::vector<int> v;
// Do lots of stuff with vector's random access iterator.
return Container(v);
}
};
int main(int argc, const char * argv[])
{
Derived der;
der.process();
//Base bs;
//bs.process();
std::cout << "done\n";
}
What are the ways in C++ to handle a class that has ownership of an instance of another class, where that instance could potentially be of a number of classes all of which inherit from a common class?
Example:
class Item { //the common ancestor, which is never used directly
public:
int size;
}
class ItemWidget: public Item { //possible class 1
public:
int height;
int width;
}
class ItemText: public Item { //possible class 2
std::string text;
}
Let's say there is also a class Container, each of which contains a single Item, and the only time anyone is ever interested in an Item is when they are getting it out of the Container. Let's also say Items are only created at the same time the Container is created, for the purpose of putting them in the Container.
What are the different ways to structure this? We could make a pointer in Container for the contained Item, and then pass arguments to the constructor of Container for what sort of Item to call new on, and this will stick the Items all in the heap. Is there a way to store the Item in the stack with the Container, and would this have any advantages?
Does it make a difference if the Container and Items are immutable, and we know everything about them at the moment of creation, and will never change them?
A correct solution looks like:
class Container {
public:
/* ctor, accessors */
private:
std::unique_ptr<Item> item;
};
If you have an old compiler, you can use std::auto_ptr instead.
The smart pointer ensures strict ownership of the item by the container. (You could as well make it a plain pointer and roll up your own destructor/assignment op/copy ctor/move ctor/ move assignment op/ etc, but unique_ptr has it all already done, so...)
Why do you need to use a pointer here, not just a plain composition?
Because if you compose, then you must know the exact class which is going to be composed. You can't introduce polymorphism. Also the size of all Container objects must be the same, and the size of Item's derived classes may vary.
And if you desperately need to compose?
Then you need as many variants of Container as there are the items stored, since every such Container will be of different size, so it's a different class. Your best shot is:
struct IContainer {
virtual Item& getItem() = 0;
};
template<typename ItemType>
struct Container : IContainer {
virtual Item& getItem() {
return m_item;
}
private:
ItemType m_item;
};
OK, crazy idea. Don't use this:
class AutoContainer
{
char buf[CRAZY_VALUE];
Base * p;
public:
template <typename T> AutoContainer(const T & x)
: p(::new (buf) T(x))
{
static_assert(std::is_base_of<Base, T>::value, "Invalid use of AutoContainer");
static_assert(sizeof(T) <= CRAZY_VAL, "Not enough memory for derived class.");
#ifdef __GNUC__
static_assert(__has_virtual_destructor(Base), "Base must have virtual destructor!");
#endif
}
~AutoContainer() { p->~Base(); }
Base & get() { return *p; }
const Base & get() const { return *p; }
};
The container requires no dynamic allocation itself, you must only ensure that CRAZY_VALUE is big enough to hold any derived class.
the example code below compiles and shows how to do something similar to what you want to do. this is what in java would be called interfaces. see that you need at least some similarity in the classes (a common function name in this case). The virtual keyword means that all subclasses need to implement this function and whenever that function is called the function of the real class is actually called.
whether the classes are const or not doesn't harm here. but in general you should be as const correct as possible. because the compiler can generate better code if it knows what will not be changed.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class outputter {
public:
virtual void print() = 0;
};
class foo : public outputter {
public:
virtual void print() { std::cout << "foo\n"; }
};
class bar : public outputter {
public:
virtual void print() { std::cout << "bar\n"; }
};
int main(){
std::vector<outputter *> vec;
foo *f = new foo;
vec.push_back(f);
bar *b = new bar ;
vec.push_back(b);
for ( std::vector<outputter *>::iterator i =
vec.begin(); i != vec.end(); ++i )
{
(*i)->print();
}
return 0;
}
Output:
foo
bar
Hold a pointer (preferably a smart one) in the container class, and call a pure virtual clone() member function on the Item class that is implemented by the derived classes when you need to copy. You can do this in a completely generic way, thus:
class Item {
// ...
private:
virtual Item* clone() const = 0;
friend Container; // Or make clone() public.
};
template <class I>
class ItemCloneMixin : public Item {
private:
I* clone() const { return new I(static_cast<const I&>(*this); }
};
class ItemWidget : public ItemCloneMixin<ItemWidget> { /* ... */ };
class ItemText : public ItemCloneMixin<ItemText> { /* ... */ };
Regarding stack storage, you can use an overloaded new that calls alloca(), but do so at your peril. It will only work if the compiler inlines your special new operator, which you can't force it to do (except with non-portable compiler pragmas). My advice is that it just isn't worth the aggravation; runtime polymorphism belongs on the heap.
I have a user interface with a tree view on the left, and a viewer on the right (a bit like an email client). The viewer on the right displays the detail of whatever I have selected in the tree on the left.
The user interface has "add", "edit" and "delete" buttons. These buttons act differently depending on what "node" in the tree is selected.
If I have a node of a particular type selected, and the user clicks "edit", then I need to open the appropriate edit dialog for that particular type of node, with the details of that node.
Now, there's a lot of different types of node and implementing a visitor class feels a bit messy (currenty my visitor has about 48 entries....). It does work nicely though - basically for editing a have something like an OpenEditDialog class that inherits the visitor, and opens the appropriate edit dialog:
abstractTreeNode->accept(OpenEditDialog());
The problem is I have to implement the abstract visitor class for every "action" I want to perform on the node and for some reason I can't help thinking I'm missing a trick.
The other way could of been to implement the functions in the nodes themselves:
abstractTreeNode->openEditDialog();
I'm ording the node around a bit here, so maybe this is better:
abstractTreeNode->editClickedEvent();
I can't help but think this is polluting the node though.
I did think of a third way that I've not given that much thought yet. I could have a templated wrapper class that gets added to the tree instead which allows me to perhaps call free-functions to perform whatever actions, so I guess as it acts as a go between for nodes and interface:
(pseudo code off the top of my head just to give an idea):
template <class T>
TreeNode(T &modelNode)
{
m_modelNode = modelNode;
}
template <>
void TreeNode<AreaNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete AreaNode
}
template <>
void TreeNode<LocationNode>::editClickedEvent()
{
openEditDialog(m_modelNode); // Called with concrete LocationNode
}
etc..
So this is effectively extending the nodes but in a different way to using the visitor and it seems a little bit neater.
Now before I go ahead and take the plunge using one of these methods, I thought it'd be wise to get some input.
Thanks! I hope all this makes some sense..
EDIT:
I've mocked up the templated wrapper idea..
class INode
{
public:
virtual ~INode() {}
virtual void foo() = 0;
};
class AreaNode : public INode
{
public:
AreaNode() {}
virtual ~AreaNode() {}
void foo() { printf("AreaNode::foo\r\n"); }
};
class RoleNode : public INode
{
public:
RoleNode() {}
virtual ~RoleNode() {}
void foo() { printf("RoleNode::foo\r\n"); }
};
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() : m_node() {}
virtual ~MainViewTreeNode() {}
void bar() {}
void foo() { m_node.foo(); }
protected:
T m_node;
};
template <>
void MainViewTreeNode<AreaNode>::bar()
{
printf("MainViewTreeNode<AreaNode>::bar\r\n");
}
template <>
void MainViewTreeNode<RoleNode>::bar()
{
printf("MainViewTreeNode<RoleNode>::bar\r\n");
}
int _tmain(int argc, _TCHAR* argv[])
{
MainViewTreeNode<RoleNode> role;
MainViewTreeNode<AreaNode> area;
std::list<ITreeNode*> nodes;
nodes.push_back(&role);
nodes.push_back(&area);
std::list<ITreeNode*>::iterator it = nodes.begin();
for (; it != nodes.end(); ++it)
{
(*it)->foo();
(*it)->bar();
}
getchar();
return 0;
}
Thanks.
Visitor is useful when you have many operations and few types. If you have many types, but few operations, use normal polymorphism.
Instead of using m_node.foo(), what you should do is static inheritance. This is basically your "template wrapper" idea, but it's a well-established pattern.
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() : m_node() {}
virtual ~MainViewTreeNode() {}
void bar() {}
void foo() { m_node.foo(); }
protected:
T m_node;
};
becomes
class ITreeNode
{
public:
virtual ~ITreeNode() {}
virtual void bar() = 0;
virtual void foo() = 0;
};
template <class T>
class MainViewTreeNode : public ITreeNode
{
public:
MainViewTreeNode() {}
virtual ~MainViewTreeNode() {}
void bar() { T::bar(); }
void foo() { T::foo(); }
};
class RoleNode : public MainViewTreeNode<RoleNode> {
void bar() { std::cout << "Oh hai from RoleNode::bar()! \n"; }
void foo() { std::cout << "Oh hai from RoleNode::foo()! \n"; }
};
Of course, if you already have regular inheritance in the mix, why not just use that? There's not going to be any easier solution than normal polymorphism here. It works well when the number of types is high and the number of operations is low. Perhaps the flaw in your design is how many types you have.
Such problems are, unfortunately, all too common with C++ and statically typed OO languages in general. I recently stumbled into this article which describes how to implement double dispatch with a custom-made lookup table.
I can see a similar approach working here. Basically, you build a table of function wrappers of the type Entry below:
class EntryBase {
public:
virtual bool matches(TreeNode const &node) const = 0;
virtual void operator()(TreeNode &node) const = 0;
};
template<typename NodeType, typename Functor>
class Entry : public EntryBase {
Functor d_func;
public:
Entry(Functor func) : d_func(func) { }
virtual bool matches(TreeNode const &node) const {
return dynamic_cast<NodeType const *>(&node) != 0;
}
virtual void operator()(TreeNode &node) const {
d_func(dynamic_cast<NodeType &>(node));
}
};
Each such table would then represent one type of Visitor (you can do this without Boost too, of course):
class NodeVisitor {
typedef boost::shared_ptr<EntryBase> EntryPtr;
typedef std::vector<EntryPtr> Table;
Table d_entries;
public:
template<typename NodeType, typename Functor>
void addEntry(Functor func) {
EntryPtr entry(new Entry<NodeType, Functor>(func));
d_entries.push_back(entry);
}
void visit(TreeNode &node) {
EntryPtr entry = lookup(node);
if (!entry)
return; // this Visitor doesn't handle this type
(*entry)(node);
}
private:
EntryPtr lookup(TreeNode &node) {
Table::const_iterator iter =
std::find_if(d_entries.begin(), d_entries.end(),
boost::bind(&EntryBase::matches, _1, boost::ref(node)));
if (iter != d_entries.end())
return *iter;
return 0;
}
};
Construction of a table would be something like this:
void addToCompany(CompanyNode &company) { ... }
void addToEmployee(EmployeeNode &employee) { ... }
NodeVisitor nodeAdder;
nodeAdder.addEntry<CompanyNode>(&addToCompany);
nodeAdder.addEntry<EmployeeNode>(&addToEmployee);
After all that work, you could simply write (without any additions to TreeNode or any class that inherits from TreeNode):
nodeAdder.visit(someNode);
The templates ensure that the dynamic_cast always succeeds, so it's quite safe. The largest drawback is, of course, that it's not the fastest in the world. But for opening a dialog, the user is probably the slower factor, so it should be quite fast enough.
I just implemented this visitor in my own project, and it is working like a charm!
Another pattern to consider here is the Command pattern. You make your nodes store a list of commands that all have GetName & Execute methods. When a node is selected you enumerate the collection and call GetName on each command to get the menu items' name and when a menu item is clicked you call Execute. This gives you ultimate flexibility, you can set up the commands when the tree is created or in each node type's constructor. Either way you get to reuse commands accross types and have varying numbers of commands for each type.
Generally though, my experience would suggest that both this and the visitor pattern are probably overkill in this case and simply putting virtual Add, Edit and Delete methods on the base tree node type is the way to go.