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?

Catskul
  • 17,916
  • 15
  • 84
  • 113
  • 1
    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. – johnathan May 10 '12 at 21:41
  • 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. – johnathan May 10 '12 at 21:44
  • 5
    @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. – Mike Seymour May 10 '12 at 22:16
  • @CrazyEddie Murray Cumming: http://mail.gnome.org/archives/gtkmm-list/2002-August/msg00233.html – Catskul May 10 '12 at 23:02
  • @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. – Catskul May 10 '12 at 23:03
  • @MikeSeymour i stand corrected,oops – johnathan May 10 '12 at 23:14
  • Well, bogus as it is...that would seem to be their reasoning... – Edward Strange May 10 '12 at 23:29
  • 1
    @murrayc sometimes answers here, maybe he can enlighten us. – ergosys May 10 '12 at 23:37
  • 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. – underscore_d Dec 18 '19 at 10:34

1 Answers1

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.

murrayc
  • 2,103
  • 4
  • 17
  • 32
  • 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. – Catskul May 27 '12 at 18:51
  • 3
    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. – murrayc May 29 '12 at 08:59
  • 1
    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. – Catskul May 29 '12 at 19:45
  • 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->()? – gauteh Mar 11 '14 at 12:06
  • 1
    gauteh, you should not store widgets via RefPtrs. – murrayc Apr 16 '14 at 08:19
  • @murrayc 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. – underscore_d Dec 06 '15 at 13:13
  • 2
    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: https://developer.gnome.org/gtkmm/stable/classGtk_1_1Builder.html#ae525dfa187377dcdc1179a52df3d160a – murrayc Dec 07 '15 at 09:40
  • This flies in the absolute face of https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters. – PBS Jun 19 '22 at 13:43
  • And it also breaks the core guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#f7-for-general-use-take-t-or-t-arguments-rather-than-smart-pointers – PBS Jun 23 '22 at 07:34