Consider the following Enum Class in Java:
package com.gousslegend.deepov;
public enum Color
{
WHITE, BLACK;
private Color opposite;
static
{
WHITE.opposite = BLACK;
BLACK.opposite = WHITE;
}
public Color getOppositeColor()
{
return opposite;
}
}
How can I achieve the same thing with C++11?
Is is possible to have enum methods with C++11?
Should I put my enum in a separate class/file with C++?
Thanks
How can I achieve the same thing with C++11?
In C++ you would be better off defining an enum, along with a free-standing function:
enum Color {BLACK, WHITE};
Color getOppositeColor(Color c) {
static Color opposite[] = {WHITE, BLACK};
return opposite[c];
}
If you are set on modeling Java exactly, make a class with two static members BLACK and WHITE, and use it instead of enum. The use would be limited, though: for instance, you wouldn't be able to use your enum values in switch cases.
Is is possible to have enum methods with C++11?
No
Should I put my enum in a separate class/file with C++?
You should put enum definition and a function prototype in a header; implementation of the function goes in a separate C++ file.
C++'s enums are simple enumerated values, they're not full-fledged classes (enum classes in C++ only provide some additional type-safety).
I would take the following approach to implement the equivalent to how Java's enums are used here:
// Header file
class Color {
Color *opposite_p;
public:
Color(Color *opposite_pArg) : opposite_p(opposite_pArg) {}
Color &opposite() { return *opposite_p; }
static Color WHITE, BLACK;
};
// .C file
Color Color::WHITE(&BLACK);
Color Color::BLACK(&WHITE);
Then, Color::WHITE.opposite() returns Color::BLACK, and COLOR::BLACK.oppsoite() returns Color::WHITE.
Related
I should start by saying I'm fairly new to OOP. I am trying to write a portable class which will probably be used in multiple programs. The class requires multiple enumerated lists to store information which are only relevant to the class so I was planning on nesting the enum inside the class. My questions are
Is there any reason to use an enum class inside a class, or should I just use enum? Just curious. I posted sample code for reference below.
Is there any reason why it would be a really bad idea to make enums in a class public?
#include <iostream>
enum class Color {
red = 0,
green = 1,
blue = 2
};
class CodeLibray {
public:
enum Color2 {
red = 0,
green = 1,
blue = 2
};
enum class Color3 {
red = 0,
green = 1,
blue = 2
};
Color color;
Color2 color2;
Color3 color3;
};
int main(){
CodeLibray c;
c.color = Color::red;
c.color2 = CodeLibray::Color2::blue;
c.color3 = CodeLibray::Color3::blue;
}
Is there any reason to use an enum class inside a class, or should I just use enum? Just curious. I posted sample code for
reference below.
It's pretty obvious that the enum values defined inside CodeLibray would become ambigous if you omit the enum class there.
Also, If I want enums to be accessible for assigning public member values but I do not want values in the enum to be changed is this
possible?
I don't fully understand what you mean. Just a shot in the dark, something like the following?
enum Color2 {
red = ::red,
// ^^ Refer to the enum declaration in the global namespace
green = ::green,
blue = ::blue
};
enum class Color3 {
red = ::red,
green = ::green,
blue = ::blue
};
I have a class Color that holds values for the red, green, blue, and alpha channels of a color. The class constructor lets you create a new color by specifying values for the four channels. However, for convenience, I would also like to have some "premade" colors available for the programmer. For example instead of having something like
DrawBox(new Color(255, 0, 0));
you would be able to say
DrawRectangle(Color::Red);
Where Color.Red is an instance of Color that lives inside the Color class. How can I declare these instances of Color inside the Color class? I'm sure there's a name for this technique, but I had no idea what search terms to use when I was looking for help online.
I'm not using any built-in or publicly-available classes or libraries because this is part of a personal exercise in creating a basic graphics stack.
Thanks for your help!
First of all, avoid using new. You could use Color as simple value-type.
Now as an answer to your question, yes, you can do that as:
//color.h
typedef unsigned char byte;
class Color
{
public:
//declaration
const static Color Red;
const static Color Green;
const static Color Blue;
public:
Color(byte red, byte green, byte blue);
};
//define the static members in color.cpp file
#include "color.h"
const Color Color::Red(255,0,0);
const Color Color::Green(0,255,0);
const Color Color::Blue(0,0,255);
Then use Color::Red as you want to use.
I have class like following:
class Car
{
public:
Car();
// Some functions and members and <b>enums</b>
enum Color
{
Red,
Blue,
Black
};
Color getColor();
void setColor(Color);
private:
Color myColor;
}
I want to:
access to Color values as Color::Red. It is really hardly to understand code when Car::Red is used, when class have a lot enums, subclasses etc.
use type Color as function argument or return value
use variable type Color in switch
I know 3 partial solutions:
Using embedded class Color and enum in it
Using embedded namespace Color and enum in it
Using enum class
1 and 2 solutions solves a Color::Red accession problem, but I can't use functions like Color getColor() and void setColor(Color).
3 solution has a problem: VS2010 doen't support enum class. GCC v.4.1.2 doesn't support it too. I don't know about later versions of gcc.
Yes, I'm working on cross-platform project.
I have found this solution, but it seems ... heavy.
I hope somebody can help me here :)
In current C++ (i.e. C++11 and beyond), you can already access enum values like that:
enum Color { Red };
Color c = Color::Red;
Color d = Red;
You can go further and enforce the use of this notation:
enum class Color { Red };
Color c = Color::Red;
// Color d = Red; <-- error now
And on a sidenote, you now define the underlying type, which was previously only possible with hacky code (FORCEDWORD or so anyone?):
enum class Color : char { Red };
Name the enum inside the nested class (as example one):
class Car
{
public:
struct Color
{
enum Type
{
Red,
Blue,
Black
};
};
Color::Type getColor();
void setColor(Color::Type);
};
When I want to do something like this I tend to use a namespace and a typedef outside of th namespace (though usually I'm doing this globally rather than inside a class). Something like this:
namespace colors
{
enum Color
{
Red,
Blue
...
}
}
typedef colors::Color Color;
This way you use the namespace to get at the actual colors, but the Color type itself is still globally accessible:
Color myFav = colors::Red;
I have an assignment in which I need to translate some Ada code to C++ code, making it as similar as possible to the Ada code. The Ada code is as follows
type Shape is (Circle, Triangle, Rectangle);
type Colors is (Red, Green, Blue);
type Figure(Form: Shape := Circle) is
record
Filled: Boolean;
Color: Colors;
case Form is
when Circle =>
Diameter: Float;
when Triangle =>
Left_Side: Integer;
Right_Side: Integer;
Angle: Float;
when Rectangle =>
Side_1: Integer;
Side_2: Integer;
end case;
end record;
I know I could use a class but judging by the language of the question and the personality of the teacher I assume he is looking for a struct. I am just unclear as to how to create the logic required for the different cases inside of a struct. The teacher is very particular so I assume that the smallest memory footprint is required.
I am a CSc student so forgive me if the solution is simple.
Thanks!
Update:
So the final answer was simpler than I thought.
enum Shape {Circle, Triangle, Rectangle};
enum Colors {Red, Green, Blue};
struct Figure {
bool Filled;
Colors Color;
Shape Form;
union {
float Diameter;
struct {
int Left_Side;
int Right_Side;
float Angle;
} tri;
struct {
int Side_1;
int Side_2;
} rect;
};
};
As usual I overthought it. Thanks for all your input!
It looks like you are suppose to derive classes Circle, Triangle, and Rectangle from a base Shape class. There are common properties (Filled, Color) that needs to go into your base Shape, and derived classes will have diameter, or left-right sides, or other additional properties.
An alternative would be to have a type-id field (enum {Circle, Rectangle, ..})in a Shape struct and a union field holding different sub-structures for diameter and other type dependent members. This would look more like the example (and C) but less like C++.
For non-class based answer:
Make the enumerations for the Shape and Color types.
Make structs for the Circle, Triangle, and Rectangle data.
Make a Figure struct containing the filled field, colored field, and a field which is a union of the structs made in #2.
[optional] Make "constructors" for the various shapes that return the struct from #3, properly initialized.
In the following code snippet, the Color enum is declared within the Car class in order to limit the scope of the enum and to try not to "pollute" the global namespace.
class Car
{
public:
enum Color
{
RED,
BLUE,
WHITE
};
void SetColor( Car::Color color )
{
_color = color;
}
Car::Color GetColor() const
{
return _color;
}
private:
Car::Color _color;
};
(1) Is this a good way to limit the scope of the Color enum? Or, should I declare it outside of the Car class, but possibly within its own namespace or struct? I just came across this article today, which advocates the latter and discusses some nice points about enums: http://gamesfromwithin.com/stupid-c-tricks-2-better-enums.
(2) In this example, when working within the class, is it best to code the enum as Car::Color, or would just Color suffice? (I assume the former is better, just in case there is another Color enum declared in the global namespace. That way, at least, we are explicit about the enum to we are referring.)
If Color is something that is specific to just Cars then that is the way you would limit its scope. If you are going to have another Color enum that other classes use then you might as well make it global (or at least outside Car).
It makes no difference. If there is a global one then the local one is still used anyway as it is closer to the current scope. Note that if you define those function outside of the class definition then you'll need to explicitly specify Car::Color in the function's interface.
Nowadays - using C++11 - you can use enum class for this:
enum class Color { RED, BLUE, WHITE };
AFAII this does exactly what you want.
I prefer following approach (code below).
It solves the "namespace pollution" problem, but also it is much more typesafe (you can't assign and even compare two different enumerations, or your enumeration with any other built-in types etc).
struct Color
{
enum Type
{
Red, Green, Black
};
Type t_;
Color(Type t) : t_(t) {}
operator Type () const {return t_;}
private:
//prevent automatic conversion for any other built-in types such as bool, int, etc
template<typename T>
operator T () const;
};
Usage:
Color c = Color::Red;
switch(c)
{
case Color::Red:
//некоторый код
break;
}
Color2 c2 = Color2::Green;
c2 = c; //error
c2 = 3; //error
if (c2 == Color::Red ) {} //error
If (c2) {} error
I create macro to facilitate usage:
#define DEFINE_SIMPLE_ENUM(EnumName, seq) \
struct EnumName {\
enum type \
{ \
BOOST_PP_SEQ_FOR_EACH_I(DEFINE_SIMPLE_ENUM_VAL, EnumName, seq)\
}; \
type v; \
EnumName(type v) : v(v) {} \
operator type() const {return v;} \
private: \
template<typename T> \
operator T () const;};\
#define DEFINE_SIMPLE_ENUM_VAL(r, data, i, record) \
BOOST_PP_TUPLE_ELEM(2, 0, record) = BOOST_PP_TUPLE_ELEM(2, 1, record),
Usage:
DEFINE_SIMPLE_ENUM(Color,
((Red, 1))
((Green, 3))
)
Some references:
Herb Sutter, Jum Hyslop, C/C++ Users Journal, 22(5), May 2004
Herb Sutter, David E. Miller, Bjarne Stroustrup Strongly Typed Enums (revision 3), July 2007
In general, I always put my enums in a struct. I have seen several guidelines including "prefixing".
enum Color
{
Clr_Red,
Clr_Yellow,
Clr_Blue,
};
Always thought this looked more like C guidelines than C++ ones (for one because of the abbreviation and also because of the namespaces in C++).
So to limit the scope we now have two alternatives:
namespaces
structs/classes
I personally tend to use a struct because it can be used as parameters for template programming while a namespace cannot be manipulated.
Examples of manipulation include:
template <class T>
size_t number() { /**/ }
which returns the number of elements of enum inside the struct T :)
If you are creating a code library, then I would use namespace. However, you can still only have one Color enum inside that namespace. If you need an enum that might use a common name, but might have different constants for different classes, use your approach.