Why does Glibmm/Gtkmm not include the unary dereferencing operator, *, for Glib::RefPtr?
Asked Answered
D

1

12

Glib::RefPtr allows dereferencing via '->' but not via '*'. Why is this?

I can of course do:

 class Foo {};
 Glib::RefPtr<Foo> fooPtr;

 fooPtr.operator->();

The docs specifically mention that they left operator*() out. But they do not offer any guidance as to why.

Edited with example for clarity:

I've seen it argued that "you should never need to dereference" a RefPtr, but IMO that seems bogus counterintuitive as any function that wants to be used with both dynamically and stack allocated objects would need the lowest common denominator interface, i.e. pass-by-reference.

Take, for instance the following example:

struct Foo 
{ 
    void print() { printf( "Success" ); } 
};

void myFunc( const Foo & foo ) { foo.print(); }

int main()
{
    Foo               foo0;
    Glib::RefPtr<Foo> foo1Ptr( new Foo );

    myFunc(  foo0    );
    myFunc( *foo1Ptr ); // error, no operator*()

    return 0;
}

Anyone know why this position is taken by the Glib team?

Davidson answered 10/5, 2012 at 20:56 Comment(9)
By looking at the documentation on that smart pointer it appears that the GLib team never intended it to be used on anything other than class types with member variables and functions. IMHO the std::unique_ptr, or std::shared_ptr would be better suited for use if you needed a pointer to non class types. And if a function takes objects thats fine, the -> operator returns the pointed to type, and its functions are accessible as it was a class type, with normal pointer semantics. That doesn't affect what arguments a function takes or returns.Alcine
And to wit, the standard smart pointers lack an operator*(), and instead have a get() member function that allows access to the contained pointed to type.Alcine
@jonathon: Which standard smart pointers lack operator*()? auto_ptr, unique_ptr and shared_ptr all have that operator, and weak_ptr only lacks it because it's not meant to be dereferencable.Vesicant
@CrazyEddie Murray Cumming: mail.gnome.org/archives/gtkmm-list/2002-August/msg00233.htmlDavidson
@johnathon did you intend to post that as an answer instead of a comment? posting as answer would make it easier for me to respond.Davidson
@MikeSeymour i stand corrected,oopsAlcine
Well, bogus as it is...that would seem to be their reasoning...Alit
@murrayc sometimes answers here, maybe he can enlighten us.Sky
Note that in current glibmm development branch master, Glib::RefPtr is-a std::shared_ptr, so it has operator*(). Reference counting is thus done by the stdlib, not by GLib.Editor
P
4

Some functions may take objects, or object references as args.

No, if an object should be used via a RefPtr, then no function will (or no function should) take it without RefPtr. Not having operator* avoids people doing this, meaning that APIs are forced to be correct, meaning that there are less memory management errors due to not using RefPtr. It's not there because people would misuse it, and people have a hard enough time getting the hang of smartpointers already.

If you have a real problem that you think would be solved by a RefPtr::operator*(), then you might mention the actual problem so we can (probably) show how you don't really want to use operator*() there.

Provencal answered 26/5, 2012 at 10:22 Comment(9)
Thanks for responding. Perhaps I'm mistaken, but my understanding is that certain types are validly allocated both dynamically and also sometimes perhaps on the stack. It seems to me to follow that to allow both, the use of pass-by-reference is necessary.Davidson
No, there are no glibmm or gtkmm types that can be used both ways (with RefPtr or without RefPtr). If you've seen anything that suggests otherwise, do please let us know in case you have just found a bug. Of course, other gtkmm types (that should never be used via RefPtr) , such as Widgets, can be allocated dynamically or on the stack, just like any other C++ class.Provencal
The source of the confusion for me was that I had been using RefPtr for custom types to avoid using several types of smart pointers.Davidson
I store a bunch of custom widgets using RefPtrs, and if I want to add the widget to a Gtk::Notebook I need to pass in a widget (I keep a copy of the refptr for as long as the widget is contained in the Notebook). The Notebook only takes pointer to widgets, not refptrs, how can I do that without using .operator->()?Nichy
gauteh, you should not store widgets via RefPtrs.Provencal
@Provencal Not even Widgets returned by-pointer from a Builder? Should I own those via a unique_ptr instead? I thought using a RefPtr might be a good idea - in the sense that it could 'collaborate' with the Builder's management of the pointers (if any) - but comments like this suggest not.Editor
unique_ptr<> might indeed be useful if the widget is a top-level widget (a window or dialog, for instance), but child widgets are created managed (see Gtk::manage()). The Gtk::Builder::get_widget() documentation mentions this: developer.gnome.org/gtkmm/stable/…Provencal
This flies in the absolute face of herbsutter.com/2013/06/05/….Bruns
And it also breaks the core guidelines: isocpp.github.io/CppCoreGuidelines/…Bruns

© 2022 - 2024 — McMap. All rights reserved.