| CodeGuru Home | VC++ / MFC / C++ | .NET / C# | Visual Basic | Newsletters | VB Forums | Developer.com |
|
|
|||||||
| 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++. |
![]() |
|
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
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++? |
|
#2
|
||||
|
||||
|
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;
}
}
__________________
"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 |
|
#3
|
|||
|
|||
|
Re: dynamic return type
Quote:
![]() 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? |
|
#4
|
|||
|
|||
|
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.
|
|
#5
|
|||
|
|||
|
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));
}
};
Regards, Paul McKenzie |
|
#6
|
|||
|
|||
|
Re: dynamic return type
Quote:
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 |
|
#7
|
||||
|
||||
|
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 |
![]() |
| Bookmarks |
|
||||||
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|