8 Replies - 343 Views - Last Post: 10 January 2013 - 01:01 PM Rate Topic: -----

#1 GryphonClaws  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 37
  • Joined: 09-December 12

How to make a variable that can contain 'flags'

Posted 10 January 2013 - 02:42 AM

Like the title says, I want to make a variable in my classes that I can pass bitwised flags to like I have seen in OpenGL. So I can do stuff like:

class Dude
{
  protected:
     ThisIsTheVariable flag;
// blah blah
}

Dude.flag = EATING | BREATHING | ALIVE;



... Or something like that.

I'm assuming I need to use a struct or something but I tried that and it didn't work so I'm wondering how anyone else has done/would do it. Thanks in advance.

Is This A Good Question/Topic? 0
  • +

Replies To: How to make a variable that can contain 'flags'

#2 GryphonClaws  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 37
  • Joined: 09-December 12

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 03:07 AM

struct ObjectFlags
{
	enum ObjectType 
	{ 
		VISIBLE = 0x1,
		INVISIBLE = 0x2,
		COLLIDE = 0x3,
		NO_COLLIDE = 0x4
	};

	ObjectType type;
	
	ObjectFlags( ObjectType t )
	{
		type = t;
	};
};



Ok got this to work, however if you'd like to comment or post how you have accomplished this, I'd appreciate it.

edit:

Is there a way I can use this without having to do this?
#include "Object.h"

Object::Object() : _hVelocity( 0.0f ), _vVelocity( 0.0f ), _type( (ObjectFlags::ObjectType)(ObjectFlags::INVISIBLE | ObjectFlags::COLLIDE) )
{
}

Object::~Object()
{
// Ignore this being in the destructor it's just for the sake of my question
// Why do I have to precede the flags with ObjectFlags::ObjectType?
	_type = (ObjectFlags::ObjectType)(ObjectFlags::COLLIDE | ObjectFlags::VISIBLE);
}


This post has been edited by GryphonClaws: 10 January 2013 - 03:14 AM

Was This Post Helpful? 0
  • +
  • -

#3 Aphex19  Icon User is offline

  • Born again Pastafarian.
  • member icon

Reputation: 614
  • View blog
  • Posts: 1,873
  • Joined: 02-August 09

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 04:48 AM

When representing flags as a bit-field, it makes sense to represent each flag as an individual bit. With that in mind, I'd make the values in ObjectType bit-masks for each flag, as well as methods to set or reset any given flag.
Was This Post Helpful? 0
  • +
  • -

#4 snoopy11  Icon User is offline

  • Engineering ● Software
  • member icon

Reputation: 770
  • View blog
  • Posts: 2,249
  • Joined: 20-March 10

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 05:55 AM

Hi,

Usually I would do it like this

#include <Windows.h>
#include <iostream>

#define EATING 0x01
#define BREATHING 0x02
#define ALIVE (EATING|BREATHING)
#define DEAD 0x16



class Dude
{
 
protected:
	
public:
    Dude();
	~Dude();
	WORD flag;
	 
// blah blah
};
Dude::Dude()
{
	flag =0;
}

Dude::~Dude()
{}

int main()
{
	Dude cowboy;
	cowboy.flag = EATING|BREATHING;

	if(cowboy.flag == ALIVE)
	{
		std::cout <<"He's Alive ";
	}
	else
		std::cout << "He's Dead";

	std::cin.ignore();
	std::cin.get();

return 0;
}



but Aphex19's idea is also good.

Regards

Snoopy.
Was This Post Helpful? 0
  • +
  • -

#5 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2102
  • View blog
  • Posts: 3,207
  • Joined: 21-June 11

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 06:07 AM

View PostGryphonClaws, on 10 January 2013 - 11:07 AM, said:

struct ObjectFlags
{
	enum ObjectType 
	{ 
		VISIBLE = 0x1,
		INVISIBLE = 0x2,
		COLLIDE = 0x3,
		NO_COLLIDE = 0x4
	};

	ObjectType type;
	
	ObjectFlags( ObjectType t )
	{
		type = t;
	};
};



With that code COLLIDE, COLLIDE | VISIBLE and COLLIDE | INVISIBLE are actually all the same value (3). Flags that aren't combinations of other flags should be powers of 2. Flags that aren't powers of 2 (i.e. flags that have more than one bit set) can always be expressed as a combination of other flags.

You also shouldn't have mutually exclusive flags. The way you set it up, it would be possible to, say, OR INVISIBLE and VISIBLE together, which probably makes no sense in your context (or any context). If you just use VISIBLE and COLLIDE as your flags, you can express invisibility and no collision by the absence of the flags (that is something is invisible if it does not have the VISIBLE flag set and it has no collision if it doesn't have the COLLISION flag set).
Was This Post Helpful? 1
  • +
  • -

#6 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3552
  • View blog
  • Posts: 11,013
  • Joined: 05-May 12

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 06:19 AM

Depending on your needs, bit fields are also an option:
struct StateFlags
{
    bool bEating    : 1;
    bool bBreathing : 1;
    bool bAlive     : 1;
};



When used in combination with unions, and intimately knowing your compiler's packing behavior, you can also access the flags as a single integer value.

This post has been edited by Skydiver: 10 January 2013 - 06:20 AM

Was This Post Helpful? 0
  • +
  • -

#7 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2957
  • View blog
  • Posts: 10,181
  • Joined: 08-August 08

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 09:12 AM

View PostSkydiver, on 10 January 2013 - 09:19 AM, said:

When used in combination with unions, and intimately knowing your compiler's packing behavior, you can also access the flags as a single integer value.

That seemed interesting, so I wrote this:
#include <iostream>

using namespace std;

class flags {
	unsigned int theflag;
	
public:
	
	void showflags() {
		printf("0x%X\n",theflag);
	}
	
	void set_flag(int num) {
		unsigned int temp = 1<<num;
		theflag |= temp;
	}
	
	void unset_flag(int num) {
		unsigned int temp = 1<<num;
		theflag &= ~temp;
	}
	
	bool is_flag_set(int num) {
		unsigned int flagset, temp = 1<<num;
		flagset = temp & theflag;
		if (flagset > 0) {
			return true;
		}
		return false;
	}

};

int main(int argc, const char * argv[])
{
	flags myflags;
	myflags.set_flag(1);
	myflags.showflags();
	myflags.set_flag(2);
	myflags.showflags();
	cout << "First test\n";
	for (int i = 0; i < 8; i++) {
		if (myflags.is_flag_set(i)) {
			cout << "Flag "<< i << " is set\n";
		} else {
			cout << "Flag "<< i << " is not set\n";
		}
	}
	myflags.unset_flag(2);
	myflags.showflags();
	cout << "Second test\n";
	for (int i = 0; i < 8; i++) {
		if (myflags.is_flag_set(i)) {
			cout << "Flag "<< i << " is set\n";
		} else {
			cout << "Flag "<< i << " is not set\n";
		}
	}
	myflags.unset_flag(1);
	myflags.showflags();
	cout << "Third test\n";
	for (int i = 0; i < 8; i++) {
		if (myflags.is_flag_set(i)) {
			cout << "Flag "<< i << " is set\n";
		} else {
			cout << "Flag "<< i << " is not set\n";
		}
	}
	
	return 0;
}


Maybe I'm missing something though, since I'm not sure what you mean by knowing the compiler's packing order. I admit I haven't fully tested this and I'm assuming that an unsigned int takes 4 bytes as it does on my system, giving me 32 flags to play with, but is there more you're thinking about?
Was This Post Helpful? 0
  • +
  • -

#8 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 0
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 09:19 AM

Check out my Traffic Lights challenge for an example of bit flags and their use.
Was This Post Helpful? 0
  • +
  • -

#9 GryphonClaws  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 37
  • Joined: 09-December 12

Re: How to make a variable that can contain 'flags'

Posted 10 January 2013 - 01:01 PM

Awesome! Thanks for all the responses. This as been a great help, thank you all.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1