STL vector...

Started by
7 comments, last by mrmrcoleman 19 years, 4 months ago
Jeez, I hate having two threads on the same forum but I have so many problems that I have no choice!? I have a class which contains an STL vector of pointers to class ScreenEntityBase. In one of the methods within this class I need to be able to get a pointer to a specific ScreenEntityBase object within the list so that I can invoke methods within it. So I created a function called FindEntity (see class).

class Screen
{
#ifndef SCREEN_H
#define SCREEN_H

#include "ScreenEntityAnimation.h"
#include "ScreenEntityStaticImage.h"
#include "ScreenEntityText.h"

// Screen class
class Screen
{
public:
        ScreenEntityBase* FindEntity(WCHAR* SearchString);
	
private:
	vector<ScreenEntityBase*> ScreenEntityList;
};

#endif
}

How should I define this method? I had thought this might work:

ScreenEntityBase* Screen::FindEntity(WCHAR* SearchString)
{
        for(vector<ScreenEntityBase*>::iterator walker = ScreenEntityList.begin();walker != ScreenEntityList.end();walker++)
        {
                if(wcscmp((walker*)->GetName(), SearchString)
                {
                        return (walker*);
                        break;
                }
        }
        return 0;
}

Will this work? Thanks in advance. Mark Coleman
Advertisement
There's a couple of syntax errors. But yeah, you've got the basic idea right.
Thanks, I will go and give it whirl...

Mark Coleman
I think you want *walker instead of walker*

I don't know if it will make a difference on your compiler, but you might want to do "++walker" instead of "walker++" in your for loop. Using the post-increment your compiler might make a copy of the walker object before it does the actual increment.
What are the access patterns for ScreenEntityList like? If most of the time you're prosessing the entire list then vector is probably a good choice (although deque may be better depending on its growth patterns). If you often need to access elements by name then a map may be a better way to go.

Also, prefer algorithms to hand-written loops:
template <class TYPE>class GetByName{	public:		GetByName(std::wstring name)			:			name_(name)		{		}		bool operator()(const TYPE& object) const		{			return object->GetName() == name_;		}	private:		std::wstring name_;};ScreenEntityBase* Screen::FindEntity(std::wstring SearchString){	ScreenEntityBase* entity = std::find_if(ScreenEntityList.begin(), ScreenEntityList.end(), GetByName<std::wstring>(SearchString));	if (entity == ScreenEntityList.end())	{		return null;	}	return *entity;}


Enigma
You don't need the break statement after the return, since you're returning execution can't continue anyway :)

Also, if you're calling FindEntity() a lot and there are a fair few entries in your vector then it might be worth checking out std::map. Using std::map it would look something like this.....
class Screen{public:    ScreenEntityBase* FindEntity(const std::wstring& SearchString);private:    typedef std::map<std::wstring,ScreenEntityBase*> ScreenEntityMap;    ScreenEntityMap screenEntities;};ScreenEntityBase* Screen::FindEntity(const std::wstring& SearchString){    ScreenEntityMap::iterator it = screenEntities.find(SearchString);    return (it!=screenEntities.end() ? *it : NULL);}
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Would that actually be more efficient Enigma? Cause it certinly isn't more readible.
Quote:Original post by Enigma
Also, prefer algorithms to hand-written loops:

For anything more substantial I'd agree, but IMHO with simple cases such as this your only making it harder to read. Switching to std::wstring is good thing though.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
Wow! So much input guys!

Most of the access is sequential and there are only ever 5-50 elements in the list at any one time so speed isn't really an issue.

Also I will drop the break!

A big thank you.

Mark Coleman

This topic is closed to new replies.

Advertisement