CodeGuru Forums -
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic Newsletters VB Forums Developer.com


Newest CodeGuru.com Articles:

  • Faltering Windows support
  • Internet Explorer 8 Click Clever Click Safe
  • Release Candidate 2 for ASP.NET MVC 2
  • Learn How to Create Dual Mode Windows Services

  • Search CodeGuru:
     



    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)
    FAQ Members List Calendar Search Today's Posts Mark Forums Read

    C++ (Non Visual C++ Issues) Ask or answer C and C++ questions not related to Visual C++. This includes Console programming, Linux programming, or general ANSI C++.

    Reply
     
    Thread Tools Search this Thread Rate Thread Display Modes
      #1    
    Old September 9th, 2009, 01:31 AM
    jlund3 jlund3 is offline
    Junior Member
     
    Join Date: Sep 2009
    Posts: 4
    jlund3 is an unknown quantity at this point (<10)
    dynamic return type

    public <T extends Actor> T getFirstInstance(Class<T> cls)
    {
    for(Actor actor : actors())
    if(cls.isInstance(actor))
    return (T) actor;
    return null;
    }

    This nifty bit of Java code allows you to pass in a class and and then find the first instance of that class in some collection. The return type is dynamic so outside this method no casting is needed. Is there any slick way of doing something similar in C++?
    Reply With Quote
      #2    
    Old September 9th, 2009, 05:14 AM
    JohnW@Wessex's Avatar
    JohnW@Wessex JohnW@Wessex is offline
    Senior Member
     
    Join Date: Jul 2002
    Location: Southampton. United Kingdom
    Posts: 1,974
    JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+)
    Re: dynamic return type

    Translating the features from one language into another is not always the best idea and can result in some ugly and inefficient code.

    That said, this does a similar task.
    It's not quite as slick and may be slow due to the dynamic_cast.
    Code:
    #include <vector>
    #include <algorithm>
    #include <functional>
    #include <iostream>
    #include <string>
    
    //******************************************
    class Base
    {
    public:
        Base(const std::string &name) : name(name){}
        virtual ~Base(){}
    
        std::string name;
    };
    
    //******************************************
    class A : public Base
    {
    public:
        A(const std::string &name) : Base(name){}
    };
    
    //******************************************
    class B : public Base
    {
    public:
        B(const std::string &name) : Base(name){}
    };
    
    //******************************************
    class C : public Base
    {
    public:
        C(const std::string &name) : Base(name){}
    };
    
    //******************************************
    template <typename TClass>
    struct Is_Instance_Of
    {
        bool operator()(Base *pb)
        {
            return (dynamic_cast<TClass *>(pb) != 0);
        }
    };
    
    //******************************************
    template <typename TClass>
    TClass *Get_First_Instance(const std::vector<Base *> &base_list)
    {
        const std::vector<Base *>::const_iterator item = std::find_if(base_list.begin(),
                                                                      base_list.end(),
                                                                      Is_Instance_Of<TClass>());
     
        if (item != base_list.end())
        {
            return static_cast<TClass *>(*item);
        }
        else
        {
            return 0;
        }
    }
    
    //******************************************
    int main()
    {
        A a1("a1"), a2("a2");
        B b1("b1"), b2("b2");
        C c1("c1"), c2("c2");
    
        std::vector<Base *> base_list;
    
        base_list.push_back(&a1);
        base_list.push_back(&b1);
        base_list.push_back(&c1);
        base_list.push_back(&a2);
        base_list.push_back(&b2);
        base_list.push_back(&c2);
    
        B *pb = Get_First_Instance<B>(base_list);
    
        if (pb != 0)
        {
            std::cout << pb->name;
        }
    }
    A better option would be to re-examine what it is you want to do and find the 'C++ way'.
    __________________
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman
    Reply With Quote
      #3    
    Old September 9th, 2009, 01:34 PM
    jlund3 jlund3 is offline
    Junior Member
     
    Join Date: Sep 2009
    Posts: 4
    jlund3 is an unknown quantity at this point (<10)
    Re: dynamic return type

    Quote:
    Originally Posted by JohnW@Wessex View Post
    Translating the features from one language into another is not always the best idea and can result in some ugly and inefficient code.
    ...
    A better option would be to re-examine what it is you want to do and find the 'C++ way'.
    First off thanks a bunch. I've done a bit with template classes, but I didn't know you could use template methods like that! I suddenly have a greater appreciation for C++.

    Anyways, I have been trying to think of a more 'C++ way' of doing this, which is hard since I have only done a few moderate size projects in the language. One solution I thought of was to have multiple containers, one for each of the subclasses and provide methods for getting at each one, thus avoiding the dynamic_cast. Any other ideas?
    Reply With Quote
      #4    
    Old September 9th, 2009, 01:39 PM
    Lindley Lindley is offline
    Elite Member
    Power Poster
     
    Join Date: Oct 2007
    Location: Fairfax, VA
    Posts: 6,897
    Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+) Lindley is a name known to all (1000+)
    Re: dynamic return type

    What's your underlying goal, though? I think that's the level you need to start on when developing an alternate approach to a problem, rather than trying to translate individual steps of the previous solution.
    Reply With Quote
      #5    
    Old September 9th, 2009, 01:56 PM
    Paul McKenzie Paul McKenzie is offline
    Elite Member
    Power Poster
     
    Join Date: Apr 1999
    Posts: 20,959
    Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+)
    Re: dynamic return type

    Not tested but you can try this:
    Code:
    template <typename TClass>
    struct Is_Instance_Of
    {
        bool operator()(Base *pb)
        {
            return (typeid(pb) == typeid(TClass));
        }
    };
    However, if the searching for a specific type is occuring in your generic (base) functions, then you should rethink your design. The base functions shouldn't know or care what the exact objects are in a container of base class pointers.

    Regards,

    Paul McKenzie
    Reply With Quote
      #6    
    Old September 9th, 2009, 02:04 PM
    Paul McKenzie Paul McKenzie is offline
    Elite Member
    Power Poster
     
    Join Date: Apr 1999
    Posts: 20,959
    Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+) Paul McKenzie has a reputation beyond repute (3000+)
    Re: dynamic return type

    Quote:
    Originally Posted by jlund3 View Post
    Anyways, I have been trying to think of a more 'C++ way' of doing this, which is hard since I have only done a few moderate size projects in the language.
    I agree with Lindley that you should think about how to approach your problem differently, and not try to think of a C++ way to do something in Java.

    Anytime a "solution" boils down to having to know what the actual objects are in a container of objects, then the design is more than likely flawed, regardless of whether you're working in Java or C++. In that regards, IMO the isInstance() of Java seems too easy to abuse, sacrificing good design for quick results (with a bad design).

    Regards,

    Paul McKenzie
    Reply With Quote
      #7    
    Old September 10th, 2009, 04:01 AM
    JohnW@Wessex's Avatar
    JohnW@Wessex JohnW@Wessex is offline
    Senior Member
     
    Join Date: Jul 2002
    Location: Southampton. United Kingdom
    Posts: 1,974
    JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+) JohnW@Wessex is a glorious beacon of light (400+)
    Re: dynamic return type

    Although I posted the 'solution' I think I should point out that I never usually find the need to do that sort of thing, except in the very rare occasion when the 'better' solution involves vastly more code and its complexity is out of proportion to the trivial problem I'm trying to solve.
    The vast majority of the time applying polymorphism and the Visitor pattern suffice.

    It's interesting to hear C++ coders complaining that a Java feature is 'open to abuse'. That's normally a Java complaint about C++.
    __________________
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman
    Reply With Quote
    Reply

    Bookmarks
    Go Back   CodeGuru Forums > Visual C++ & C++ Programming > C++ (Non Visual C++ Issues)


    Thread Tools Search this Thread
    Search this Thread:

    Advanced Search
    Display Modes Rate This Thread
    Rate This Thread:

    Posting Rules
    You may not post new threads
    You may not post replies
    You may not post attachments
    You may not edit your posts

    BB code is On
    Smilies are On
    [IMG] code is On
    HTML code is Off
    Forum Jump


    All times are GMT -5. The time now is 08:17 AM.



    Acceptable Use Policy


    The Network for Technology Professionals

    Search:

    About Internet.com

    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers


    Powered by vBulletin® Version 3.7.3
    Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.