name based factory

Aug 12, 2016 at 2:19pm
This is similar to a question I asked previously: http://www.cplusplus.com/forum/general/151106/

I am assuming that because function pointers that are class based require a specific class name in the pointer declaration, that the table suggested in the above article would not take class function pointers for different classes.

Lets say I have a base class called BaseGraphicsObject. I want to be able to instantiate a class derived from this base class based on the name of a class from xml. A set of function pointers referenced by name as above would be a way to do it but only if the following were possible: is it be possible to call (preferably a static) function of a derived class if the function pointer declaration is for the base class? It seems a bit of a stretch to me but I thought it was worth asking. IF not, is there any other way to accomplish this?
Aug 12, 2016 at 3:06pm
..... is it be possible to call (preferably a static) function of a derived class if the function pointer declaration is for the base class?


I hope I am not being overly simplistic, but that sounds a lot like ordinary polymorphism. The declaration is for a pointer to base class, but the container has pointers to derived classes. If one were to apply a virtual function to each member of the container, the correct derived class function would be called.

Reading the following, it looks like it might work in a polymorphic fashion. I am not sure though - hopefully JLBorges :+) is not too far away. Or someone else with sufficient abilities :+D

http://en.cppreference.com/w/cpp/utility/functional/function
cppreference wrote:
Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.


This is from the example code:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};

int main()
{
// store a call to a member function
    std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
    const Foo foo(314159);
    f_add_display(foo, 1);
}


If it does work in a polymorphic fashion, then I imagine it would work for some base class of Foo as well.
Last edited on Aug 12, 2016 at 3:12pm
Aug 12, 2016 at 4:35pm
So theoretically the following should work?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
template<typename KeyType, typename ValueType>
class MyHashTemplateClass {...};

class Foo* {...};
class Bar : public Foo
{
	Bar() {...}
	Foo* createBar() { return new Bar(); }
};

class Baz : public Foo
{
	Baz() {...}
	Foo* createBaz() { return new Baz(); }
};

int main()
{
	MyHashTemplateClass<std::string, std::function<Foo*()> creatorTable;
	creatorTable.insert("Bar", &Bar::createBar);
	creatorTable.insert("Baz", &Baz::createBaz);
	Foo *object1, *object2;
	object1 = creatorTable["Bar"](); // creates a Bar instance
	object2 = creatorTable["Baz"](); // creates a Baz instance.
}
Last edited on Aug 12, 2016 at 4:42pm
Aug 13, 2016 at 3:07am
Hi,

Have thought about this a bit more, just wondering about the purpose of what you are doing with the xml - are you wanting to write xml for each object you have? If so, that strikes me as being a serialisation thing.

If that is the case, then you could have a virtual serialise function for each of your classes, which would be called in a polymorphic fashion. This follows with the OOP principle of not having to name functions with class names in them. That is, we don't want to have CircleWriteXml(), PolygonWriteXml(), PointWriteXml() etcetera, just a serialiseXml() function in each graphic object class. Just on that, in your code you have createBar and createBaz - they could both be called create(), and that function could be pure virtual in the base class.

There are different ways of doing serialisation, here is a link to some boost documentation:
http://www.boost.org/doc/libs/1_61_0/libs/serialization/doc/index.html

Edit: they have examples which don't have intrusive member functions.

I hope I have the right end of the stick here - I am trying to see through to what you a really trying to do - my guess might be completely wrong :+)

I will have a go at writing some code :+) Edit: There are lots of good examples in the documentation I linked.
Last edited on Aug 13, 2016 at 4:39am
Topic archived. No new replies allowed.