passing a pointer to base class as reference initializer

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • YaldenWere
    New Member
    • Feb 2008
    • 3

    passing a pointer to base class as reference initializer

    On gnu compiler:

    If you try to initialize a reference to a pointer to a base type, (e.g. Foo*&), with a pointer to a derived type, eg Bar*, the compiler rejects it claiming inability to match prototypes.

    Is this a gnu compiler bug or is there sanity behind its recalcitrance?
    Microsoft compiler is OK with this im told (but havent tried myself)
    For example, casting to the base type pointer prior to function call does not help. But creating a separate base class pointer and initializing it by direct cast on the derived class will work. Go figure!!

    See below:


    struct Foo {
    int a;
    double b;
    };

    struct Bar : public Foo {
    double c;
    };

    void afunc(Foo *& e) {
    e->a = 23;
    e = NULL;
    }

    void cfunc(Foo *& e) {
    e->b = 34.5;
    e = NULL;
    }

    void testfunc() {
    Foo foo;
    Foo *pfoo = &foo;
    afunc(pfoo); // works fine


    Bar bar;
    Foo *pbar = &bar;
    cfunc(pbar); // works fine, but requires explicit Foo* pointer

    // Bar *ppbar = &bar;
    // cfunc((Foo *)ppbar); // compiler don’t like this, even with explicit cast
    // I would expect
    // cfunc(ppbar); to be ok, and certainly,
    // cfunc((Foo *)ppbar); to be ok given that 6 lines above is ok by compiler
    // can someone explain what I am missing please.

    }
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    Originally posted by YaldenWere
    Bar bar;
    Foo *pbar = &bar;
    cfunc(pbar); // works fine, but requires explicit Foo* pointer

    // Bar *ppbar = &bar;
    // cfunc((Foo *)ppbar); // compiler don’t like this, even with explicit cast
    // I would expect
    // cfunc(ppbar); to be ok, and certainly,
    First, your naming convention has tripped you up. ppbar is not a pointer to a Bar*. It's a Bar*.
    Second, cfunc() takes a reference to a pointer as an argument but you do not provide the pointer to use used a reference. You attempt to do this with a cast but that won't work. You need to create an actual Foo* to be used as a reference. See below, which compiles and links:

    [[code=cpp]
    Bar *pbar1 = &bar;
    Foo* test = pbar1;
    cfunc(test);
    [/code]

    Comment

    • YaldenWere
      New Member
      • Feb 2008
      • 3

      #3
      Originally posted by weaknessforcats
      First, your naming convention has tripped you up. ppbar is not a pointer to a Bar*. It's a Bar*.
      Second, cfunc() takes a reference to a pointer as an argument but you do not provide the pointer to use used a reference. You attempt to do this with a cast but that won't work. You need to create an actual Foo* to be used as a reference. See below, which compiles and links:

      [[code=cpp]
      Bar *pbar1 = &bar;
      Foo* test = pbar1;
      cfunc(test);
      [/code]

      Thank you weaknessforcats for your response, and please excuse my novice posting etiquette.
      Your resonse is correct, however it did not help me understand that which is puzzling me. A simpler example, that does not involve functions syntax is as follows:

      Code:
        Bar bar;
        Bar *pbar  = &bar;
        Foo *pbar_ = &bar;
        
        Bar* &rpbar = pbar;
        Foo* &rpbar1 = pbar_;
        Foo* &rpbar2 = (Foo *)pbar;  // fails with compiler message as below
      error: invalid initialization of non-const reference of type 'const Foo*&' from a temporary of type 'const Foo*'

      Above,
      pbar_ is a pointer to Foo initialized with address of instance bar and can be used to initialize rpbar1, a reference to pointer to Foo

      pbar is a pointer to Bar, initialized with address of instance bar, however, even after casting it explicitly to (Foo*) it cannot be used to initialize rpbar2, a reference to pointer to Foo.

      To me,
      (Foo *)pbar; on the right hand side of = on line 7) is the same as
      pbar_; on the right hand side of = on line 6).

      Both right hand sides are of type Foo*

      1). I dont understand why they are different to the compiler
      2). I dont understand the error message that is reported.
      3). I would have expected a line 7) without the explicit cast to work because Bar is a kind of Foo.

      Can you explain all this to me?

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        Originally posted by YaldenWere
        To me,
        (Foo *)pbar; on the right hand side of = on line 7) is the same as
        pbar_; on the right hand side of = on line 6).

        Both right hand sides are of type Foo*
        It's because you are initializing a reference.

        To do that, you need an actual object to refer to. A typecast can produce a tempary object, but not always, and that temprary object does last as long as the current scope. It goes away at the end of the statement. That makes it not suitable for a reference.

        Just initilize a variable with the result of the typecast and you can refer to that.
        [code=cpp]
        Bar* &rpbar = pbar;
        Foo* &rpbar1 = pbar_;
        Foo* x = (Foo*)pbar;
        Foo*& rpbar2 = x;
        [/code]

        Comment

        • YaldenWere
          New Member
          • Feb 2008
          • 3

          #5
          Originally posted by weaknessforcats
          It's because you are initializing a reference.

          To do that, you need an actual object to refer to. A typecast can produce a tempary object, but not always, and that temprary object does last as long as the current scope. It goes away at the end of the statement. That makes it not suitable for a reference.

          Just initilize a variable with the result of the typecast and you can refer to that.
          [code=cpp]
          Bar* &rpbar = pbar;
          Foo* &rpbar1 = pbar_;
          Foo* x = (Foo*)pbar;
          Foo*& rpbar2 = x;
          [/code]

          Thanks for your input.
          I appreciate.
          Best YW

          Comment

          Working...