Overload by deriv class param; call w base class param

Discussion in 'C++' started by ectoplasm, Jul 25, 2005.

  1. ectoplasm

    ectoplasm Guest

    Abstract base class A. Derived from A are class B and C, both concrete.

    I hold a pointer to an object of class A, an instance which is either B
    or C.

    I have trouble with making the following work, while I think it should
    be possible:

    A *pA = new B; // One of...
    A *pA = new C; // ...these two
    DoSomething(pA); // Call overloaded method

    This called method is overloaded, and looks like this:

    void DoSomething(B *pB)
    {
    // Code to handle a B
    }

    void DoSomething(C *pC)
    {
    // Code to handle a C)
    }

    If this is not possible, what should I do? Is the following the only
    way?

    void DoSomething(A *pA)
    {
    if (pA->IsTypeOf(B))
    // Code to handle a B
    else if (pA->IsTypeOf(C))
    // Code to handle a C
    }

    There must be something more "OO".

    Thanks,
    E.
     
    ectoplasm, Jul 25, 2005
    #1
    1. Advertising

  2. * ectoplasm:
    >


    Make DoSomething a virtual member function of class A.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 25, 2005
    #2
    1. Advertising

  3. ectoplasm

    ectoplasm Guest

    Alf P. Steinbach, thanks. But my example simplified things and I forgot
    to mention: the methods I want to implement shall not be (virtual)
    members of A. Are there other solutions?
     
    ectoplasm, Jul 25, 2005
    #3
  4. * ectoplasm:
    > Alf P. Steinbach, thanks. But my example simplified things and I forgot
    > to mention: the methods I want to implement shall not be (virtual)
    > members of A. Are there other solutions?


    Depends what the problem is.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 25, 2005
    #4
  5. ectoplasm

    ectoplasm Guest

    The problem is, that MS VC++ gives a compile error

    error C2664: cannot convert parameter 1 from 'A *' to 'B *'

    on my call DoSomething(pA). Even though pA is a pointer to a B
    instance.

    Seems there is no way around this. A method can only take a parameter
    of its type or a derived type. In other words, can only be an
    (implicit) upcast. In my opinion, this is a failure of C++. Don't you
    agree that what I want is not strange at all but is OO functionality
    that naturally should be possible?
     
    ectoplasm, Jul 25, 2005
    #5
  6. ectoplasm

    Jack Klein Guest

    On 24 Jul 2005 20:11:43 -0700, "ectoplasm" <> wrote
    in comp.lang.c++:

    > Alf P. Steinbach, thanks. But my example simplified things and I forgot
    > to mention: the methods I want to implement shall not be (virtual)
    > members of A. Are there other solutions?


    Why not?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 25, 2005
    #6
  7. ectoplasm

    Jack Klein Guest

    On 24 Jul 2005 21:50:04 -0700, "ectoplasm" <> wrote
    in comp.lang.c++:

    > The problem is, that MS VC++ gives a compile error
    >
    > error C2664: cannot convert parameter 1 from 'A *' to 'B *'
    >
    > on my call DoSomething(pA). Even though pA is a pointer to a B
    > instance.
    >
    > Seems there is no way around this. A method can only take a parameter
    > of its type or a derived type. In other words, can only be an
    > (implicit) upcast. In my opinion, this is a failure of C++. Don't you
    > agree that what I want is not strange at all but is OO functionality
    > that naturally should be possible?


    No, it is not strange. C++ provides a simple method of doing it,
    providing a virtual function in the base class. What is silly is your
    arbitrary insistence that you must have functionality but won't use
    the standard mechanism that provides it.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Jul 25, 2005
    #7
  8. * ectoplasm:
    > The problem is, that MS VC++ gives a compile error
    >
    > error C2664: cannot convert parameter 1 from 'A *' to 'B *'
    >
    > on my call DoSomething(pA). Even though pA is a pointer to a B
    > instance.


    That is not the problem, it's the compiler telling you you've chosen a bad
    way to solve the problem.


    > Seems there is no way around this. A method can only take a parameter
    > of its type or a derived type. In other words, can only be an
    > (implicit) upcast. In my opinion, this is a failure of C++. Don't you
    > agree that what I want is not strange at all but is OO functionality
    > that naturally should be possible?


    What you seem to want is not OO, it's the opposite.

    However, my earlier comment stands: make 'DoSomething' a virtual member
    function of class A. You then wrote, "the [two] methods I want to implement
    shall not be (virtual) members of A", but that's OK. Here's one way --
    and note that it's just a technical solution, it _does not_ solve the real
    problem, which is at the design level, not the language level, and unknown:

    #include <iostream>
    #include <ostream>

    class B;
    class C;

    static void doSomething( B* )
    {
    std::cout << "doSomething( B* )" << std::endl;
    }

    static void doSomething( C* )
    {
    std::cout << "doSomething( C* )" << std::endl;
    }

    class A
    {
    private:
    virtual void doSomething() = 0;
    public:
    static void doSomething( A* arg ) { arg->doSomething(); }
    };

    class B: public A
    {
    private:
    virtual void DoSomething()
    {
    ::doSomething( this );
    }
    };

    class C: public A
    {
    private:
    virtual void doSomething()
    {
    ::doSomething( this );
    }
    };

    void doSomething( A* arg )
    {
    A::doSomething( arg );
    }

    int main()
    {
    A* p = new C;
    doSomething( p );
    delete p;
    }


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 25, 2005
    #8
  9. ectoplasm

    Zorro Guest

    With reference to the line:

    DoSomething(pA); // Call overloaded method

    Let us say the compiler should do it. Then, which one of the two
    overloads should it choose?

    I am trying to say that the compiler cannot resolve the ambiguity, even
    if it did implicit upcast of some sort.


    Hope that helps.
    Z.
     
    Zorro, Jul 25, 2005
    #9
  10. ectoplasm

    ectoplasm Guest

    Even though it's been a few days, I still want to comment on this
    because I think it still is like a "missing link" in C++ / OO; your
    arguments are not convincing me.

    You ask: why shall the method (DoSomething()) not be a virtual member
    of A? Answer: the method I want to call is actually a constructor of a
    dialog (CDialog class of MFC). You'll have to agree that it is not good
    design to have dialogs (UI elements) inside of a class which abstracts
    some entity (clear separation between data and visualisation). So I
    want to be able to have a dialog for a B and C class instance; they
    have a different appearance. Suppose the dialog class is simply named
    Dialog:

    class Dialog
    {
    Dialog (B *pB);
    Dialog (C *pC);
    ~Dialog();
    }

    I want to hold a pointer to type A and when I construct the dialog, I
    don't want to know whether it is really a B or C (derived) type. Only
    at the moment a dialog needs to be shown, their difference becomes
    apparent (inside of the dialog).

    Then, Zorro, you say the compiler cannot know which overload to choose.
    Right, but what about virtual calls, the vtable...? To make the above
    work, the only thing the compiler might want to check if the method
    DoSomething() has overrides for all types derived from A. Maybe also
    have a default implementation at the base level (A).

    Concluding, I wouldn't know why there cannot be overloads of (non
    member) functions based on the parameter's common base class. You say
    it is not OO, I say it definitely is. It is not a far-fetched idea and
    you can easily find real world analogies for this situation.
     
    ectoplasm, Jul 27, 2005
    #10
  11. ectoplasm

    ectoplasm Guest

    N.b.: the dialog constructor is analogous to the DoSomething() method;
    I mixed them up in my last post. Sorry for that.
     
    ectoplasm, Jul 27, 2005
    #11
  12. * ectoplasm:
    > N.b.: the dialog constructor is analogous to the DoSomething() method;
    > I mixed them up in my last post. Sorry for that.


    Well you have already got working code to solve your language-level problem,
    so what is the fuzz all about?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Jul 27, 2005
    #12
  13. ectoplasm

    Zorro Guest

    > Then, Zorro, you say the compiler cannot know which overload to choose.

    All I am saying is the following (using your class example).

    Given that p is a pointer to base, what is expected from the line:

    Dialog MyDiag(p);

    Forget about the compiler. What would you do? Would you create an
    instance using type B or C?

    Regards,

    http://www.zhmicro.com
    http://distributed-software.blogspot.com
     
    Zorro, Jul 28, 2005
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Geathaa
    Replies:
    2
    Views:
    726
    Geathaa
    Jul 30, 2003
  2. Piotre Ugrumov
    Replies:
    3
    Views:
    395
    Nick Hounsome
    Jan 25, 2004
  3. Alf P. Steinbach
    Replies:
    6
    Views:
    572
    John Carson
    Sep 3, 2005
  4. Ying-Chieh Liao

    function overload (not operator overload)

    Ying-Chieh Liao, Oct 11, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    281
    Sherm Pendley
    Oct 11, 2004
  5. Dave
    Replies:
    5
    Views:
    751
    John Bokma
    Apr 26, 2011
Loading...

Share This Page