How to Automatically Register a Class on Creation

How to automatically register a class on creation

You can indeed do this using the curiously recursive template idiom. It requires nothing from whoever is extending the class that can't be enforced by the compiler:

template<class T>
struct Animal
{
Animal()
{
reg; //force specialization
}
virtual std::string name() = 0;
static bool reg;
static bool init()
{
T t;
AnimalManager::registerAnimal(t.name());
return true;
}
};

template<class T>
bool Animal<T>::reg = Animal<T>::init();

struct Tiger : Animal<Tiger>
{
virtual std::string name() { return "Tiger"; }
};

In this code, you can only extend Animal if you specialize it. The constructor forces the static member reg to be initialized, which in turn calls the register method.

EDIT: As pointed out by @David Hammen in the comments, you won't be able to have a collection of Animal objects. However, this can easily be solved by having a non-template class from which the template inherits and use that as a base class, and only use the template for extending.

How to auto register a class when it's defined

Yes, meta classes can do this. A meta class' __new__ method returns the class, so just register that class before returning it.

class MetaClass(type):
def __new__(cls, clsname, bases, attrs):
newclass = super(MetaClass, cls).__new__(cls, clsname, bases, attrs)
register(newclass) # here is your register function
return newclass

class MyClass(object):
__metaclass__ = MetaClass

The previous example works in Python 2.x. In Python 3.x, the definition of MyClass is slightly different (while MetaClass is not shown because it is unchanged - except that super(MetaClass, cls) can become super() if you want):

#Python 3.x

class MyClass(metaclass=MetaClass):
pass

As of Python 3.6 there is also a new __init_subclass__ method (see PEP 487) that can be used instead of a meta class (thanks to @matusko for his answer below):

class ParentClass:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
register(cls)

class MyClass(ParentClass):
pass

[edit: fixed missing cls argument to super().__new__()]

[edit: added Python 3.x example]

[edit: corrected order of args to super(), and improved description of 3.x differences]

[edit: add Python 3.6 __init_subclass__ example]

Automatically Register Class to the Window

One way of doing this would be to create a function for registering a class. [Classes] have a name property which you can use for registering the name in the global space. This does require you to declare your classes inside of a function but without some kind of code transformation being done before the code hits the browser, it's about the best you can do.

function register(c) {  console.log('Registering ' + c.name);  window[c.name] = c;}
register(class ClassA { constructor() { console.log('Created ClassA'); }});
register(class ClassB { constructor() { console.log('Created ClassB'); }});
register(class ClassC { constructor() { console.log('Created ClassC'); }});
new ClassA();new ClassB();new ClassC();

Auto register a class when it's defined (but without importing it anywhere)

I feel that your approach is a bit complicated to implement the functionality you want. My suggestion is to you use a strategy like this:

  1. Name your modules so that the command classes are defined in files named after the commands they implement. For example, the RebootCommand class goes into the file commands/reboot.py.
  2. Every command module defines a top-level variable command_cls that contains a reference to the class implementing the command. commands/reboot.py would therefore contain code like this:

    class RebootCommand:
    def execute(self):
    # [...]

    command_cls = RebootCommand
  3. To execute a command, you use the __import__ function to dynamically load your module. Your CommandManager.py would logically live in a file outside the commands directory (which is reserved for command modules) and would be implemented like the following:

    class CommandManager:
    @classmethod
    def execute(cls, command, *args, **kw):
    # import the command module
    commands_mod = __import__("commands", globals(), locals(), [command])
    mod = getattr(commands_mod, command)
    return mod.command_cls(*args, **kw).execute()

EDIT: Seems I confused the usage of the imp module. Updated the code to use __import__.

Automatic registration of derived classes in a factory pattern

Your code looks too complicated to me. Maybe there is a reason that I miss.

You cannot avoid the registration. What you are looking for is registration at compile time, which I think it is not possible. Since you are looking for registration at compile time, it means that you do not need to expose the registration method in interface. So, your client interface should be made of the base class and a creation method:

// { client interface header
class B
{
public:
virtual ~B() = 0 {}
//...
};

B* Create( const char* s );
// } client interface header

A simple creation function:

// { client interface implementation

template< typename T >
B* New()
{
return new T;
}

typedef B* (*PFNew)();

B* Create( const char* s )
{
typedef std::map< string, PFNew > Map;

static Map m;
if ( ! m.size() )
{
m[ D1::Signature() ] = New< D1 >;
m[ D2::Signature() ] = New< D2 >;
//...
}

Map::const_iterator ci = m.find( s );
if ( ci == m.end() )
throw -1;
return ci->second();
}

// } client interface implementation

C# make class auto-register

I have checked with other resources (that are quite knowledgeable about the internals of the CLR and IL) and it seems that this is a hole in the CLR and the C# language. There simply is no direct way of making things automatically happen on assembly load or appdomain preparation. Walking the types and finding the types that I'm interested in is the least bad way.
In fact, attributes aren't always created until some piece of code asks for them, so I can't use an attribute constructor with a type argument to auto-register, either!

This is of course not great, because if there are eight different pieces of code that each have their own kind of registration they want to do, each of those pieces have to iterate through all of the types and do the inspection on their own. The only way around that would be to give up on modularity, and make all of the different "things" that happen to types be centralized to a single walk-all-types loop at the start of the app. Third party libraries (including the MEF) still wouldn't go inside this loop, though, so there's just an unavoidable chunk of overhead here, OR an unavoidable piece of duplication -- my choice, as developer.

Python: How to register all child classes with the father class upon creation

you can use meta classes for that:

class AutoRegister(type):
def __new__(mcs, name, bases, classdict):
new_cls = type.__new__(mcs, name, bases, classdict)
#print mcs, name, bases, classdict
for b in bases:
if hasattr(b, 'register_subclass'):
b.register_subclass(new_cls)
return new_cls

class AbstractClassA(object):
__metaclass__ = AutoRegister
_subclasses = []

@classmethod
def register_subclass(klass, cls):
klass._subclasses.append(cls)

@classmethod
def get_concrete_classes(klass):
return klass._subclasses

class ConcreteClassA1(AbstractClassA):
pass

class ConcreteClassA2(AbstractClassA):
pass

class ConcreteClassA3(ConcreteClassA2):
pass

print AbstractClassA.get_concrete_classes()

I'm personnaly very wary of this kind of magic. Don't put too much of this in your code.

Best way to for C++ types to self register in a list?

You can execute something before main once if a instantiation of a template is made. The trick is to put a static data member into a class template, and reference that from outside. The side effect that static data member triggers can be used to call the register function:

template<typename D>
struct automatic_register {
private:
struct exec_register {
exec_register() {
persistenceSystem::registerPersistableType(
D::getPersister()
);
}
};
// will force instantiation of definition of static member
template<exec_register&> struct ref_it { };

static exec_register register_object;
static ref_it<register_object> referrer;
};

template<typename D> typename automatic_register<D>::exec_register
automatic_register<D>::register_object;

Derive the class you want to be auto-registered from automatic_register<YourClass> . The register function will be called before main, when the declaration of referrer is instantiated (which happens when that class is derived from, which will implicitly instantiate that class from the template).

Having some test program (instead of the register function, a function do_it is called):

struct foo : automatic_register<foo> {    
static void do_it() {
std::cout << " doit ";
}
};

int main() {
std::cout << " main ";
}

Yields this output (as expected):

doit main

automatic registration of object creator function with a macro

I find your concept pretty complicated and I'm not sure if it's required. From my point of view your problem can be circumvented when adding the following code:

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

struct Object{}; // Value Object

// provide a simple create function to derived classes
template<class T> struct ObjectT : public Object {

static Object* create() { return new T(); }
};

struct ObjectFactory {

std::map<std::string, Object* (*)()> creators_factory;

static ObjectFactory* instance()
{
static ObjectFactory* __self = NULL;
if (__self == NULL)
__self = new ObjectFactory();

return __self;

}

template <class T> bool reg(const std::string& id, Object* (*creator)() )
{
creators_factory[id] = creator;
return true;
}

// pass in creator function pointer to register it to id
static Object* create(const std::string& id) {
return instance()->creators_factory[id]();
}

};

#define REGISTER_CHAIN(T) bool isRegistered_##T = ObjectFactory::instance()->reg<T>(#T, T::create)

struct DerivedA : public ObjectT<DerivedA> { DerivedA() { std::cout << "DerivedA constructor\n"; } };
REGISTER_CHAIN(DerivedA);

struct DerivedB : public ObjectT<DerivedB> { DerivedB() { std::cout << "DerivedB constructor\n"; } };
REGISTER_CHAIN(DerivedB);

struct DerivedC : public ObjectT<DerivedC> { DerivedC() { std::cout << "DerivedC constructor\n"; } };
REGISTER_CHAIN(DerivedC);

struct DerivedD : public ObjectT<DerivedD> { DerivedD() { std::cout << "DerivedD constructor\n"; } };
REGISTER_CHAIN(DerivedD);

int main(void)
{
// Call last link in the register chain to register all object creators
//ObjectFactory::Register<LAST_CHAIN_LINK>::chain();
delete ObjectFactory::create("DerivedA");
delete ObjectFactory::create("DerivedB");
delete ObjectFactory::create("DerivedC");
delete ObjectFactory::create("DerivedD");
return 0;
}

I hope this helps.

Best regards,
Martin

Any way to trigger creation of a list of all classes in a hierarchy in Swift 4?

I'm answering my own question; maybe it'll help someone else.

My goal is to auto initialize subclasses such that they can register with a central authority and allow the application to retrieve a list of all such classes. As I put in my edited question, above, there doesn't appear to be a way to do this in Swift. I have confirmed this now.

I've tried a bunch of different techniques and nothing seems to work. My goal was to be able to add a .swift file with a class in it and rebuild, and have everything automagically know about the new class. I will be doing this a little differently, though.

I now plan to put all subclasses that need to be initialized this way into a particular directory in my application bundle, then my AppDelegate (or similar class) will be responsible for invoking a method that scans the directory using the filenames as the class names, and instantiating each one, thus building the list of "registered" subclasses.

When I have this working, I'll come back and post the code here (or in a GitHub project and link to it).



Related Topics



Leave a reply



Submit