Pepelee
Pepelee

Reputation: 453

Dynamically generate Class-Constructor out of String

In my information-model there are more then 400 data types, which are named like this: AutomationDomainType. The types (constructor and members) are generated out of a modeller, but unfortunately there is no destructor generated. So I have to implement their destructors and call them in my main function:

void deleteObjectTypeUA(OpcUa_UInt16 ObjID, OpcUa_UInt16 NsIdx)
{

if (ObjID == PrefixId_AutomationDomainType)
    {
        NodeManagerRoot* pNodeManagerRoot = NodeManagerRoot::CreateRootNodeManager();
        auto dummyTypeInstance = new NamespacePrefix::AutomationDomainTypeBase(UaNodeId(PrefixId_AutomationDomainType, 2),
            UaString("Dummy_AutomationDomainType"), 2, pNodeManagerRoot);
        dummyTypeInstance->~AutomationDomainTypeBase();
        delete dummyTypeInstance;
    }

I have to manually implement the destructors in the data-type .cpps, but in my deleteType function I don't want to make 400 if else conditions to create a DummyObject, and after that the destructor (I create the dummyobject in order to call the destructor of the Class, not a good implementation but it works and isn't really the topic ;) )

A bit more insight: in my information model there are

  1. a DataType-Object, and
  2. instance-Objects of that type.

In the destructors I want to delete all instances of that type (they are tagged in a list). This all happens in the specific datatype.cpp file though. The DummyObject is only created in order to call the destructor (to delete the instances)

is there a possibility in c++ with some magic to generate this 2 lines in the snippet with the information of the ObjID?

auto dummyTypeInstance = new NamespacePrefix::AutomationDomainTypeBase(UaNodeId(NamespacePrefixId_AutomationDomainType, 2),
            UaString("Dummy_AutomationDomainType"), 2, pNodeManagerRoot);

// ...

dummyTypeInstance->~AutomationDomainTypeBase();

I don't want to use a script to generate the code (it would be too long).

Upvotes: 0

Views: 74

Answers (1)

Tezirg
Tezirg

Reputation: 1649

I think what you are looking for is templating.

Let's define a generic templated function that works for any types

template <typename BaseDomainType_T, unsigned int PrefixID>
void deleteObject(unsigned int ObjID) {
  if (ObjID == PrefixID)
   {
      NodeManagerRoot* pNodeManagerRoot = NodeManagerRoot::CreateRootNodeManager();
      auto dummyTypeInstance = new BaseDomainType_T(UaNodeId(PrefixID, 2),
      UaString("Dummy_AutomationDomainType"), 2, pNodeManagerRoot);
      delete dummyTypeInstance;
   }
}

Let's define some dummy types to use. These are your generated types

typedef int BaseTypeOne;
typedef unsigned int BaseTypeTwo;

Use the templated function with every combination we have

void deleteObjectTypeUA(unsigned int ObjID, unsigned int NsIdx) {
    //For base type 1
    deleteObject<BaseTypeOne, 0>(ObjID);
    deleteObject<BaseTypeOne, 1>(ObjID);
    deleteObject<BaseTypeOne, 2>(ObjID);
    deleteObject<BaseTypeOne, 3>(ObjID);
    //For base type 2
    deleteObject<BaseTypeTwo, 0>(ObjID);
    deleteObject<BaseTypeTwo, 1>(ObjID);
}

Upvotes: 1

Related Questions