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;
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
};
UPDATE: I just did some benchmarking of the core conversion logic for various solutions. Here are the CPU times in nanoseconds for a single iteration, averaged out of five million iterations on Wandbox:
8 - switch statement
176 - static map
3800 - dynamic map
As you can see, creating a new map every time (dynamic mapping) is relatively time consuming. Creating the map once (static mapping) and just referring to it thereafter is almost 22 times faster. But, coincidentally, the original switch-based solution is 22 times faster than static mapping!
Hmm... I never considered dynamic mapping a viable solution but had hopes for static mapping. It's quite a bit slower than the good, old switch statement, but does 8 nanoseconds versus 176 nanoseconds really matter?
End of update
The core problem I'm trying to solve is translating from one "namespace" to another (in the general sense, not re the C++ namespace keyword). This is common in programming, usually solved in C++ with a switch statement like this:
#include <iostream>
enum MUSIC { ROCK, RAP, EDM, COUNTRY };
enum COLOR { RED, BLUE, ORANGE, WHITE };
COLOR convert(MUSIC music)
{
COLOR color = WHITE;
switch (music) {
case RAP: color = RED; break;
case EDM: color = BLUE; break;
case ROCK: color = RED; break;
}
return color;
}
int main()
{
COLOR c = convert(COUNTRY);
std::cout << c << std::endl;
}
The following is my solution (the templates will be tucked away in a header file somewhere). The convert() function works with any types that are valid for std::map, e.g., enum to enum and long to std::string. The first parameter is the key, or "from" value, the second is the default value if can't be converted, and the return value is the mapped, or "to," value. (Special thanks to #Yakk for help with template argument deduction.)
#include <iostream>
#include <map>
#include "boost/assign.hpp"
template<class T> struct no_deduction { typedef T type; };
template<typename Key, typename T>
T convert(const Key &k, const T &d, const typename no_deduction<std::map<Key, T> >::type &m) {
typename std::map<Key, T>::const_iterator it = m.find(k);
return it == m.end() ? d : it->second;
}
using boost::assign::map_list_of;
enum MUSIC { ROCK, RAP, EDM, COUNTRY };
enum COLOR { RED, BLUE, ORANGE, WHITE };
int main()
{
COLOR c = convert(COUNTRY, WHITE, map_list_of (RAP, RED) (EDM, BLUE) (ROCK, RED));
std::cout << c << std::endl;
}
Anyway, notice that map_list_of, above, creates the same list every time it's called. I'd like it to be static. This is the obvious solution:
static const std::map<MUSIC, COLOR> m = map_list_of (RAP, RED) (EDM, BLUE) (ROCK, RED);
COLOR c = convert(COUNTRY, WHITE, m);
But I'm trying to make it simple to use, in particular, as a single statement. Here's a macro solution, but I'd rather avoid that, too.
#define CONVERT(f,t,d,m) do{static const std::map<BOOST_TYPEOF(f), BOOST_TYPEOF(d)> m_ =\
map_list_of m; t = convert(f, d, m_);}while(0)
COLOR c;
CONVERT(COUNTRY, c, WHITE, (RAP, RED) (EDM, BLUE) (ROCK, RED));
Does anybody know of some C++ magic (C++03, actually) that can call my convert() function
with a static map,
as a single statement, and
without using a macro?
Why not just simply use a static array and index it ?
enum MUSIC { ROCK = 0, RAP = 1, EDM = 2, COUNTRY = 3 };
enum COLOR { RED, BLUE, ORANGE, WHITE };
static const COLOR music_to_color[] =
{
RED, //maps to 'ROCK = 0'
BLUE, //maps to 'RAP = 1'
ORANGE, //maps to 'EDM = 2'
WHITE //maps to 'COUNTRY = 3'
};
MUSIC music = RAP;
std::cout << music_to_color[music] << std::endl;
The body of your convert function can be only return music_to_color[music] (where music would be the argument) in this case.
The advantages of this approach are speed and lack of additional runtime overhead of creating a std::map of something simmilar. Disadvantage would be the fact that you cannot easily modify the map on runtime and it is more "C-like" than "C++ like" (you can ease the pain using std::array instead of static array if you need C++ interface: iterators, etc.)
Another way to do the same thing is to use template specializations, but it is a lot of typing and it would be difficult to maintain if you had a lot of values to map.
Uppercase names are conventionally reserved for macros, so I renamed them.
At some point you are going to have to do the work of coding how one enum type converts to another. The easiest way using a map is as follows:
Color convert(Music music)
{
static const std::map<Music, Color> converter = { { Rap, Red }, { Edm, Blue }, { Rock, Red } };
return converter.at(music);
}
This uses initializer lists which is a C++11 feature. If you can't use that, you can try:
Color convert(Music music)
{
static const struct Once
{
Once()
{
converter[Rap] = Red;
converter[Edm] = Blue;
converter[Rock] = Red;
}
std::map<Music, Color> converter;
} once;
std::map<Music, Color>::const_iterator find_it = once.converter.find(music);
assert(find_it != once.converter.end());
return find_it->second;
}
This code might not use fancy macros but it's safe, reasonably efficient (one instance of the map) and readable (although I did do a trick with that struct there). There are faster ways but they are more complicated and probably not necessary for your use case.
If there are less than a dozen enum values, I would consider just using a switch statement however. It is usually faster than a map.
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.
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 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.