TClass::New for class without default constructor

Hello,

I am trying to create a new instance of a class which doesnt have a default constructor. The constructor takes an std::string. A dictionary has been created for it, and I can create new instances of the class through PyROOT:

>>> import ROOT
>>> a = ROOT.MyClass("myString")

So that works fine. I am just trying to figure out how I could do the same on the C++ side. The following only works if a default constructor is available:

root [0] MyClass* a = (MyClass*)(TClass::GetClass("MyClass")->New()); //this fails

So how am I supposed to pass the string for the constructor in the C++ side? I am using 6.04/12

Thanks
Will

Hi Will,

why would you like to invoke TClass to create an instance of your class and not the class header?
I see you use ROOT 6.04. If you just need the class for interactivity, it’s not necessary to have dictionaries for the class: you can just include its header and load the library where it’s implemented.
Have a look here
mybinder.org/repo/cernphsft/rootbinder
section “Interactive 3rd Party Libs”

Cheers,
Danilo

>>> a = ROOT.MyClass("myString")

The C++ syntax for this is

root [] MyClass a("myString");

or

root [] auto a = new MyClass("myString");

Cheers,
Philippe.

Hi both,

Sorry, I really should have been clearer. I know I can use the classes like you say, but I really want to do it via a ‘factory method’ approach. This is because I am actually going to use this code in a compiled code where the implementation of the class is not included in the library that gets compiled (and linked against).

So I really do want to know how to do it via TClass::New.

Hi,

[quote]So I really do want to know how to do it via TClass::New.[/quote]This is currently not forseen through this interface. However there are a couple of alternative. For example you could do

void *addr = gROOT->ProcessLineFast("new MyClass(\"someString\");"); or the interpreter even more directly via TCallFunc or ClassInfo_t and CallFunc_t.

Cheers,
Philippe

Ok, thanks for confirming. Shame it’s not as simple as the PyROOT method :frowning:

Hi,

just a clarification. When you are writing

ROOT.MyClass("myarg")

you are indeed invoking from Python the constructor of the class via the meta layer of ROOT, e.g. what Philippe pointed out mentioning TCallFunc.
If you do not want to go that route, it is always possible to write a simple library with one simple method

void* myClassFactory(){[...]};

and invoke it from within your C++ application.

Cheers,
Danilo

Hi Danilo,

For completness sake, TCallFunc is also capable of calling the constructor (with argument) directly.

Cheers,
Philippe.

Absolutely!