Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7812681
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T04:35:34+00:00 2026-06-02T04:35:34+00:00

Inspired by answer Johannes Schaub’s answer I tried to implement a reflective factory. The

  • 0

Inspired by answer Johannes Schaub’s answer I tried to implement a reflective factory. The idea is that you can create objects by passing the name of the class to a method which creates the concerning object on the heap and returns a pointer to a common base class. Using dynamic_cast and RTTI the objects can be casted back to their original type if necessary. One should be able to use the reflective factory as shown below:

// Base is the base class of all objects to create.
class Factory: public AbstractFactory<Base>
{
public:
    Factory()
    {
        m_map["DerivedA"] = &AbstractFactory::createInstance<DerivedA>;
        m_map["DerivedB"] = &AbstractFactory::createInstance<DerivedB>; 
    }
};

int main()
{
    Factory factory;
Base *a = factory.Create("DerivedA");
DerivedA *aa = dynamic_cast<DerivedA*>(a);

    // etc..
}

I got this working so far. However there are two main problems I have with the code below. It is ugly and if I make the methods of the abstract factory protected it complaints that it cannot access the createInstance() method. This is something I do not understand. By definition the derived class should be able to access the protected methods of the base class. I tested the code in VS 2008. Further notes: I know the base class is not really abstract, because it does not contain a pure virtual function. I know about std::function however so far I haven’t used it. Maybe I’ll do in the future.

#include <iostream>
#include <map>
#include <typeinfo>
#include <string>

struct Base
{
    virtual std::string SayHello() = 0;
};

struct DerivedA: public Base
{

    virtual std::string SayHello() 
    {
        return "Hello from DerivedA";
    }

};

struct DerivedB: public Base
{

    virtual std::string SayHello() 
    {
        return "Hello form DerivedB";
    }

};

/**
 * @brief Reflective Factory class. Creates objects of classes which derive from
 *        a common base class.
 *
 */
template<class BASE_T>
struct AbstractFactory
{

// Macro to call ptrs to member functions as recommended in the C++ FAQ lite.
// http://www.parashift.com/c++-faq-lite/pointers-to-members.html
#define CALL_MEMBER_FN(object, ptrToMember) ((object).*(ptrToMember))

    // Recall funcion ptr syntax for members: ReturnType (class::*) (Arguments)

    // using a typedef makes it easier..
    typedef BASE_T*  (AbstractFactory::*func_ptr_type) ();
    // retType^ ClassName^ AliasName^  Arguments^

    typedef std::map<std::string, func_ptr_type> map_type;

    template<typename DERIVED_T> 
    BASE_T * createInstance() 
    { return new DERIVED_T; }

    map_type m_map;

    /**
     * @brief Creates an object from a class with the name given as string.             
     */
    BASE_T * Create(std::string className)
    {
        // Note the last () at the end.
        return CALL_MEMBER_FN(*this, m_map[className])();
    }

#undef CALL_MEMBER_FN

};

class Factory: public AbstractFactory<Base>
{

public:

    Factory()
    {
        m_map["DerivedA"] = &AbstractFactory::createInstance<DerivedA>;
        m_map["DerivedB"] = &AbstractFactory::createInstance<DerivedB>; 
    }

};

int main()
{
    Factory factory;

    Base *a = factory.Create("DerivedA");

    DerivedA *aa = dynamic_cast<DerivedA*>(a);

    std::cout << typeid(a).name()  << std::endl;
    std::cout << typeid(*a).name()  << std::endl;
    std::cout << typeid(aa).name() << std::endl;

    std::cout << aa->SayHello() << std::endl;

    std::cin.get();

    return 0;
}

Update

The exact error I get using VS 2008 is (in German, sorry was not my choice..)

1>------ Erstellen gestartet: Projekt: ReflectiveFactory, Konfiguration: Debug Win32 ------
1>Kompilieren...
1>main.cpp
1>.\main.cpp(82) : error C2248: "AbstractFactory<BASE_T>::createInstance": Kein Zugriff auf protected Member, dessen Deklaration in der AbstractFactory<BASE_T>-Klasse erfolgte.
1>        with
1>        [
1>            BASE_T=Base
1>        ]
1>        .\main.cpp(55): Siehe Deklaration von 'AbstractFactory<BASE_T>::createInstance'
1>        with
1>        [
1>            BASE_T=Base
1>        ]
1>.\main.cpp(83) : error C2248: "AbstractFactory<BASE_T>::createInstance": Kein Zugriff auf protected Member, dessen Deklaration in der AbstractFactory<BASE_T>-Klasse erfolgte.
1>        with
1>        [
1>            BASE_T=Base
1>        ]
1>        .\main.cpp(55): Siehe Deklaration von 'AbstractFactory<BASE_T>::createInstance'
1>        with
1>        [
1>            BASE_T=Base
1>        ]
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-02T04:35:35+00:00Added an answer on June 2, 2026 at 4:35 am

    The Create method must be accessible to end users, which means that either that method is public in AbstractFactory or it is moved to Factory and made public there. The rest of the code in AbstractFactory can be protected.

    It seems that only gcc accepts the code (clang++, comeau reject it) and it could be rightfully rejected (I would have to look into the standard). At any rate a simple workaround would be to create a helper function that will provide the member function pointer for you:

    template <typename B>
    template <typename D>
    AbstractFactory<B>::func_ptr_type AbstractFactory<B>::getCreateInstancePtr() const {
       return &AbstractFactory<B>::createInstance<D>;
    }
    

    This template member method of the AbstractFactory template can be protected, as you are directly calling it on your own base in the actual Factory:

    Factory::Factory() {
            m_map["DerivedA"] = getCreateInstancePtr<DerivedA>();
            m_map["DerivedB"] = getCreateInstancePtr<DerivedB>();
    }
    

    After checking with the standard:

    11.5p1 [class.protected]

    Except when forming a pointer to member (5.3.1), the access must be through a
    pointer to, reference to, or object of the derived class itself (or any class derived from that class) (5.2.5). If the access is to form a pointer to member, the nested-name-specifier shall name the derived class (or any class derived from that class).

    That is, the expression m_map["DerivedA"] = &AbstractFactory::createInstance<DerivedA>; is incorrect, while m_map["DerivedA"] = &Factory::createInstance<DerivedA>; is correct (regarding access specifiers, but not types, the left hand side is an B* (AbstractFactory<B>::*)( std::string ) and the right hand side is a B* (Factory::*)( std::string ), so the assignment would fail.

    This plays nice with the semantics of protected everywhere else, and in particular with not being able to access the protected members of other than your own base subobject:

    class base {
    protected:
       int x;
    };
    struct derived : base {
       static void f( base& b ) {
          b.x = 5;                 // Error: cannot access base::x from this context
       }
    };
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Inspired by this answer .. Can you guys point me to something similar--something that
This question was inspired by this answer to another question, indicating that you can
Inspired by this question and answer , how do I create a generic permutations
Inspired by std::string in a multi-threaded program and another answer (seen somewhere), that STL
Inspired by the encoding scheme of the answer to this question , I implemented
This question is inspired by Jon Skeet's answer: Is there a c# equivalent to
UPDATE: Here's my solution (inspired by accepted answer): function log(msg, values) { if(config.log ==
Inspired by this answer about dynamic cast to void* : ... bool eqdc(B* b1,
I came across this answer where the poster suggested that the shorthand for if(typeof
G'day, Inspired by a comment I made in my answer to this question on

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.