[C++-sig] Static, again...
David Abrahams
dave at boost-consulting.com
Tue Nov 12 20:55:03 CET 2002
Hugo van der Merwe <hugo at adept.co.za> writes:
> I had a look at the mailing list archives about this topic, I'm still
> not clear on how exactly it works:
>
>> #include <boost/python/module.hpp>
>> #include <boost/python/class.hpp>
>>
>> struct Num {
>> Num() {}
>> ~Num() {}
>> static int getDims() {return 3;}
>> int dims() {return 5;}
>> };
>>
>> BOOST_PYTHON_MODULE_INIT(numTest)
>> {
>> using namespace boost::python;
>> module numTestMod("numTest");
>> numTestMod
>> .add
>> ( class_<Num>("Num")
>> .def_init()
>> .def("getDims",&Num::getDims)
>> .def("dims", &Num::dims)
>> )
>> ;
>> }
>
>> We don't have a way to make true static methods yet.
This part is still true.
>> getDims will work fine if you access it through the class like this:
>>
>> Nums.getDims()
I was wrong when I posted that.
> I am trying to wrap a "Settings" class which does not have a public
> constructor, it expects you to call "GetInstance" to get a pointer to
> the always-existing instance (making the settings "global"). The above
> would make me think that this will work:
>
> class_<Settings, boost::noncopyable>("Settings", no_init)
> .def("GetInstance", &Settings::GetInstance,
> return_value_policy<reference_existing_object>());
>
> I cannot call Settings.GetInstance(), it gives me:
>
> TypeError: unbound method Boost.Python.function object must be called with Settings instance as first argument (got nothing instead)
Right, that won't work.
> I also read about an approach that looks something like this:
>
> object settings_class =
> class_<Settings, boost::noncopyable>("Settings", no_init);
> settings_class.attr("Settings") = &Settings::GetInstance;
>
> But I don't know how that is supposed to work...
Yeah, that won't work either.
> If I wanted to expose GetInstance as Settings() instead (once I get it
> working), is it as simple as just calling it "__init__" instead?
Unfortunately, no. That would be cool, though, wouldn't it? I'm
pretty sure you can do this after you define class_<Settings>, though:
// Note no leading dot.
def("Settings", &Settings::GetInstance
, return_value_policy<reference_existing_object>());
This will replace the class in the module by a function called
Settings that gets the instance.
> (Should I then have no_init in the class_<> invocation or not?
Yep.
> I noticed the tutorial talks about no_init, but then mentions as
> soon as you wish to derive classes from it, you do not want
> no_init. So when is no_init useful? Only when you cannot construct a
> class and don't want to derive from it, i.e. when you're using
> "factories"?)
I think that's right. However, I wonder if we should change the
__init__ function that you get from no_init to be a no-op unless the
Python class actually has the same type as the abstract base...
> I am really astonished with what can be achieved with C++ -
> Boost.Python is really amazing!
Thank you!
--
David Abrahams
dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
More information about the Cplusplus-sig
mailing list