List of subclass pointers...

The Partridge Family were neither partridges nor a family. Discuss.
albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: List of subclass pointers...

Post by albinopapa » March 30th, 2020, 1:18 am

Just wanted to say it's a shame you aren't using std::variant. It's a pretty decent alternative to dynamic polymorphism. Here's a sample of finding an object by type using it:

Code: Select all


#include <variant>
class B0
{
	
};

class B1
{

};

class A
{
public:
	// List each sub-class type in the template parameter list of std::variant
	// Here is use 'using' to alias the type so I don't have to retype the whole thing elsewhere
	using tvar = std::variant<B0, B1>;

public:
	// Here, the A constructor can take in any type listed in the std::variant 
	// template parameter list and initialize the variant member with it
	template<typename T> A( T const& var_ ) :var( var_ ) {}

public: // vars
	tvar var;
};

// Free function for finding the first item of type "FindMe" and returning a pointer to it
// if found in the vector or nullptr otherwise.
template<typename FindMe>
FindMe* FindFirst( std::vector<A>& vars )
{
	for( auto& element : vars )
	{
		if( auto* result = std::get_if<FindMe>( &element.var ); result != nullptr )
			return result;
	}

	return nullptr;
}
You could also do something like:

Code: Select all

template<typename T>
std::vector<T*> CollectAllOf( std::vector<A>& vec )
{
	std::vector<T*> result;
	for( auto& element : vec )
	{
		if( auto* result = std::get_if<T>( &element.var ); result != nullptr )
			result.push_back( result );
	}

	return result;
}
This would collect all pointers of a specified type. If you wanted all B1 objects for instance.

Also note that in this case here, I have made it so that A is the public interface just like your polymorhpic A, but if you notice the std::vector<A> is not std::vector<A*>. This is because the compiler handles things behind the scenes to keep track of what each std::variant is actually storing. One of the reasons I find this pretty cool is how you can use it as to make a homogeneous vector or list of objects. Instead of dynamically allocating each subclass, each subclass is allocated on the stack or in the vector heap whereas a vector of polymorphic A* would have you allocate each sub-class somewhere on the heap and only storing the address in the vector.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

binbinhfr
Posts: 78
Joined: May 9th, 2019, 10:57 pm

Re: List of subclass pointers...

Post by binbinhfr » March 30th, 2020, 9:21 pm

man, the real shame is that I was not aware about this variant type !!!!
now, believe me that i'll give it a try ! ;-)

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: List of subclass pointers...

Post by albinopapa » March 31st, 2020, 4:18 am

std::variant takes some getting use to, just a heads up. I spent the better part of 6 weeks to get to the point I could use it comfortably. Not saying you'd have to take that long, but it's not as straight forward as dynamic polymorphism.

For instance, there are the global accessors: std::get<> and std::get_if<>
If you know the type, you can use std::get<> otherwise you'll throw an exception, if the type is unknown, but you have an idea or doing what I showed, then you can use std::get_if. If the template parameter is the same as the underlying type then the pointer is returned, otherwise it's nullptr.

Then there is the std::visit function. There are multiple ways of using this function to access each underlying object and their data. If you ever go down the std::variant path and want some assistance, let me know.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply