[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