How can I achieve this behaviour?

Discussion in 'C++' started by JKop, Sep 5, 2004.

  1. JKop

    JKop Guest

    class Cow
    {
    public:

    void EatGrass() const {}
    };

    class Brow
    {
    private:

    Cow cow;

    public:

    operator Cow&()
    {
    return cow;
    }
    };

    int main()
    {
    Brow k;

    k.EatGrass();
    }


    Is there any way I can achieve the above, whereby a Brow is implicitly
    converted to a Cow? Here would be another example:

    class Blah
    {
    private:

    double a;

    public:

    operator double&()
    {
    return a;
    }
    };


    int main()
    {
    Blah jk;

    jk = 52.0;
    }


    -JKop
    JKop, Sep 5, 2004
    #1
    1. Advertising

  2. "JKop" <> wrote in message
    news:W1u_c.26614$...
    > class Cow
    > {
    > public:
    >
    > void EatGrass() const {}
    > };
    >
    > class Brow
    > {
    > private:
    >
    > Cow cow;
    >
    > public:
    >
    > operator Cow&()
    > {
    > return cow;
    > }
    > };
    >
    > int main()
    > {
    > Brow k;
    >
    > k.EatGrass();
    > }
    >
    >
    > Is there any way I can achieve the above, whereby a Brow is implicitly
    > converted to a Cow?


    Yes:

    class Brow
    {
    private:

    Cow cow;

    public:

    Cow& operator. ()
    {
    return cow;
    }
    };

    :)

    Seriously .. this is a reasona to prefer non-member functions to member
    functions.

    class Brow
    {
    private:

    Cow cow;

    public:

    operator Cow&()
    {
    return cow;
    }

    operator const Cow&() const
    {
    return cow;
    }
    };

    void EatGrass(const Cow&);

    Jonathan
    Jonathan Turkanis, Sep 5, 2004
    #2
    1. Advertising

  3. JKop

    JKop Guest

    Jonathan Turkanis posted:

    >
    > "JKop" <> wrote in message
    > news:W1u_c.26614$...
    >> class Cow
    >> {
    >> public:
    >>
    >> void EatGrass() const {} };
    >>
    >> class Brow
    >> {
    >> private:
    >>
    >> Cow cow;
    >>
    >> public:
    >>
    >> operator Cow&()
    >> {
    >> return cow; } };
    >>
    >> int main()
    >> {
    >> Brow k;
    >>
    >> k.EatGrass();
    >> }
    >>
    >>
    >> Is there any way I can achieve the above, whereby a Brow is implicitly
    >> converted to a Cow?

    >
    > Yes:
    >
    > class Brow
    > {
    > private:
    >
    > Cow cow;
    >
    > public:
    >
    > Cow& operator. ()
    > {
    > return cow;
    > }
    > };
    >
    >:)


    By golly I love it!

    So now we can do the following:

    void SomeFunc(Cow& k);

    int main()
    {
    Brow t;

    SomeFunc(t); //operator Cow&
    }

    Plus we can access it's members:

    int main()
    {
    Brow t;

    t.EatGrass();
    }

    The only thing left is to access its operators:

    int main()
    {
    Brow t;

    t = 6;

    //Assuming Cow has an assignment operator
    }

    Is there any easy way to do this, other than rhyming them all off:

    class Brow
    {
    private:

    Cow f;

    public:

    operator==(const Cow& r)
    {
    return f == r;
    }

    operator*(const Cow& r)
    {
    return f * r;
    }
    };

    Templates would be required to get in all the operators and variable
    argument types.


    -JKop
    JKop, Sep 5, 2004
    #3
  4. JKop

    JKop Guest

    For christ's sake it won't compile. You can't overload "."!

    -JKop
    JKop, Sep 5, 2004
    #4
  5. Jonathan Turkanis wrote:

    > Yes:
    >
    > class Brow
    > {
    > private:
    >
    > Cow cow;
    >
    > public:
    >
    > Cow& operator. ()
    > {
    > return cow;
    > }
    > };
    >
    > :)
    >
    > Seriously .. this is a reasona to prefer non-member functions to member
    > functions.
    >
    > class Brow
    > {
    > private:
    >
    > Cow cow;
    >
    > public:
    >
    > operator Cow&()
    > {
    > return cow;
    > }
    >
    > operator const Cow&() const
    > {
    > return cow;
    > }
    > };
    >
    > void EatGrass(const Cow&);




    However constructors should be preferred when another class has to be
    made compatible with the current class, and operator types() when our
    current class has to become compatible with another class, of which we
    have no access to its definition.






    Regards,

    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Sep 5, 2004
    #5
  6. Ioannis Vranos, Sep 5, 2004
    #6
  7. "Ioannis Vranos" <> wrote in message
    news:che0ig$31hk$...
    > Jonathan Turkanis wrote:
    >
    > > Yes:
    > >
    > > class Brow
    > > {
    > > private:
    > >
    > > Cow cow;
    > >
    > > public:
    > >
    > > Cow& operator. ()
    > > {
    > > return cow;
    > > }
    > > };
    > >
    > > :)
    > >
    > > Seriously .. this is a reasona to prefer non-member functions to member
    > > functions.
    > >
    > > class Brow
    > > {
    > > private:
    > >
    > > Cow cow;
    > >
    > > public:
    > >
    > > operator Cow&()
    > > {
    > > return cow;
    > > }
    > >
    > > operator const Cow&() const
    > > {
    > > return cow;
    > > }
    > > };
    > >
    > > void EatGrass(const Cow&);

    >
    >
    >
    > However constructors should be preferred when another class has to be
    > made compatible with the current class, and operator types() when our
    > current class has to become compatible with another class, of which we
    > have no access to its definition.


    I was thinking of Cow as the class to which we didn't have access. We can still
    define Brow as above, and

    void EatGrass(const Cow& cow) { cow.EatGrass(); }

    Jonathan
    Jonathan Turkanis, Sep 5, 2004
    #7
  8. "Ioannis Vranos" <> wrote in message
    news:che0mo$31hk$...
    > JKop wrote:
    >
    > > You can't overload "."!

    >
    > Yes you can't. But I think the first one he provided was a joke.


    Right. Maybe I should have used a different smiley: :-D ???

    Jonathan
    Jonathan Turkanis, Sep 5, 2004
    #8
  9. JKop

    PKH Guest

    "JKop" <> wrote in message
    news:W1u_c.26614$...
    > class Cow
    > {
    > public:
    >
    > void EatGrass() const {}
    > };
    >
    > class Brow
    > {
    > private:
    >
    > Cow cow;
    >
    > public:
    >
    > operator Cow&()
    > {
    > return cow;
    > }
    > };
    >
    > int main()
    > {
    > Brow k;
    >
    > k.EatGrass();
    > }
    >
    >
    > Is there any way I can achieve the above, whereby a Brow is implicitly
    > converted to a Cow? Here would be another example:
    >
    > class Blah
    > {
    > private:
    >
    > double a;
    >
    > public:
    >
    > operator double&()
    > {
    > return a;
    > }
    > };
    >
    >
    > int main()
    > {
    > Blah jk;
    >
    > jk = 52.0;
    > }
    >
    >
    > -JKop


    You could also use a ClassID approach like this :
    ( a bit more code than the other suggestions, but quite powerful)

    typedef char ClassID;

    class CClassIDBase
    {
    public:
    static ClassID
    m_cClassID;

    virtual CClassIDBase* RequestClass(const ClassID& c)
    {
    return (&c == &m_cClassID) ? this : NULL;
    }
    };


    class CCow : public CClassIDBase
    {
    public:
    static ClassID
    m_cClassID;

    public:
    void EatGrass(){}
    virtual CClassIDBase* RequestClass(const ClassID& c)
    {
    return (&c == &m_cClassID) ? this : CClassIDBase::RequestClass(c);
    }
    };


    class CBrow : CClassIDBase
    {
    public:
    static ClassID
    m_cClassID;

    CCow
    m_cCow;

    public:
    virtual CClassIDBase* RequestClass(const ClassID& c)
    {
    if (&c == &CCow::m_cClassID)
    {
    return &m_cCow;
    }
    else
    {
    return (&c == &m_cClassID) ? this : CClassIDBase::RequestClass(c);
    }
    }
    };


    ClassID
    CClassIDBase::m_cClassID = 0,
    CCow::m_cClassID = 0,
    CBrow::m_cClassID = 0;


    int main(int argc, char* argv[])
    {
    CCow
    *pcCow;

    CBrow
    cBrow;

    if ((pcCow = (CCow*)cBrow.RequestClass(CCow::m_cClassID)) != NULL)
    {
    pcCow->EatGrass();
    }

    return 0;
    }
    PKH, Sep 5, 2004
    #9
  10. * JKop:
    > class Cow
    > {
    > public:
    >
    > void EatGrass() const {}
    > };
    >
    > class Brow
    > {
    > private:
    >
    > Cow cow;
    >
    > public:
    >
    > operator Cow&()
    > {
    > return cow;
    > }
    > };
    >
    > int main()
    > {
    > Brow k;
    >
    > k.EatGrass();
    > }
    >
    >
    > Is there any way I can achieve the above, whereby a Brow is implicitly
    > converted to a Cow?


    Very simple, derive Brow from Cow:

    class Brow: public Cow
    {
    };



    >Here would be another example:
    >
    > class Blah
    > {
    > private:
    >
    > double a;
    >
    > public:
    >
    > operator double&()
    > {
    > return a;
    > }
    > };
    >
    >
    > int main()
    > {
    > Blah jk;
    >
    > jk = 52.0;
    > }


    Give class Blah an assignment operator (which implies also a copy
    constructor) and perhaps also a conversion to double,

    class Blah
    {
    public:
    Blah( Blah const& another ) { ... }
    Blah( double number ) { ... }

    Blah& operator=( double number )
    {
    ...
    return *this;
    }

    operator double() const
    {
    return ...;
    }
    };

    What you cannot do (except by providing access to Blah internals)
    is to have assignments to something of 'double' type affect a Blah.

    --
    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, Sep 5, 2004
    #10
  11. JKop

    JKop Guest

    Alf P. Steinbach posted:

    > Very simple, derive Brow from Cow:



    I can't do this. At the moment I'm writing a class for a
    re-seatable reference.


    -JKop
    JKop, Sep 5, 2004
    #11
  12. * JKop:
    > Alf P. Steinbach posted:
    >
    > > Very simple, derive Brow from Cow:

    >
    > I can't do this. At the moment I'm writing a class for a
    > re-seatable reference.


    As I recall there have been discussions of allowing operator.()
    or something similar to be defined per class, but it's no help
    to you now.

    If the definition of "reference" is to be able to use "." then
    sorry, no can do in the general case.

    The language does not support that.

    --
    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, Sep 5, 2004
    #12
  13. "Jonathan Turkanis" <> wrote in message
    news:...
    >

    <<giant snip>>
    > > However constructors should be preferred when another class has to be
    > > made compatible with the current class, and operator types() when our
    > > current class has to become compatible with another class, of which we
    > > have no access to its definition.

    >
    > I was thinking of Cow as the class to which we didn't have access. We can

    still
    > define Brow as above, and
    >
    > void EatGrass(const Cow& cow) { cow.EatGrass(); }


    Maybe I'm just missing the joke, but how can the code that invokes EatGrass
    pass in a reference to a Cow object that it doesn't have access to? Whatever
    code calls EatGrass must have ownership of a Cow object to pass. So how does
    it get one? In any case, it won't be the Cow object in a Brow object, since
    that is hidden. Are you just goofing around?
    --
    Gary
    Gary Labowitz, Sep 5, 2004
    #13
  14. Alf P. Steinbach wrote:

    > As I recall there have been discussions of allowing operator.()
    > or something similar to be defined per class, but it's no help
    > to you now.
    >
    > If the definition of "reference" is to be able to use "." then
    > sorry, no can do in the general case.
    >
    > The language does not support that.



    operator.() overloading is not supported, because there is no reason to
    support that. operator->() is supported though, in case you want the
    objects to behave like pointers.






    Regards,

    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Sep 6, 2004
    #14
  15. * Ioannis Vranos:
    > Alf P. Steinbach wrote:
    >
    > > As I recall there have been discussions of allowing operator.()
    > > or something similar to be defined per class, but it's no help
    > > to you now.
    > >
    > > If the definition of "reference" is to be able to use "." then
    > > sorry, no can do in the general case.
    > >
    > > The language does not support that.

    >
    >
    > operator.() overloading is not supported, because there is no reason to
    > support that.


    That opinion is interesting.


    > operator->() is supported though, in case you want the objects
    > to behave like pointers.


    I don't think JKop is unaware of that, or of the many other possibilities
    were he to drop the main requirement & reason for existence of his class.

    --
    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, Sep 6, 2004
    #15
    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. Eric
    Replies:
    4
    Views:
    2,643
  2. Wee Bubba

    Can I achieve this with a Repeater?

    Wee Bubba, May 18, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    281
    Wee Bubba
    May 18, 2004
  3. Replies:
    4
    Views:
    6,855
    abastys
    Oct 21, 2008
  4. Fendi Baba
    Replies:
    0
    Views:
    343
    Fendi Baba
    Oct 15, 2003
  5. TB
    Replies:
    6
    Views:
    389
    Antti Virtanen
    Jun 22, 2006
Loading...

Share This Page