I am unable to find same question on this site, hence asking. I want to know how to access enum type from C file which is declared inside a class. Consider following example:
test1.h
class abc
{
public:
enum mode
{
ENTER_MODE = 0,
EXIT_MODE = 1
};
}
test2.h
abc::mode test_mode();
test2.c
abc::mode test_mode()
{
if (some_condition)
{
return abc::ENTER_MODE;
}
else
{
return abc::EXIT_MODE;
}
}
This doesn't compile. Any suggestion ?
Try to avoid using classes with C. Instead, just use structures (structures in C++ support many of the features of classes). In this example code (disregard if my assumption is wrong), there is no need for restricting the scope of the enumeration to within a class.
Ideally, you should save these as .cpp files and compile as C++. What does the compilation error say?
End the class definition with a semicolon and declare as:
enum abc::mode test_mode();
try this one (this one compiles) ok:
class abc
{
public:
enum mode
{
ENTER_MODE = 0,
EXIT_MODE = 1
};
};
enum abc::mode test_mode()
{
bool some_condition=false; // or something
if (some_condition)
{
return abc::ENTER_MODE;
}
return abc::EXIT_MODE;
}
Related
I have a class method that needs to know the value of a variable named mode which takes the values 1 an 0 and is a private attribute of the class. I want to write a setter function that can change mode to 1 or 0. However, I must use an enum to determine the new value that I should set mode to: enum sequence {error=0,active =1}; I want sequence to be an attribute (I was hoping to make it private) of the class. How can I write a setter function that takes as input active or error and sets the value of mode accordingly. Here is the basic structure of my code:
#include <iostream>
class Blink{
public:
void setter(...){
}
private:()
int mode = 0;
enum sequence {error = 0, active = 1};
};
Blink b;
int main() {
b.setter(active);
}
PS: I'm having a hard time coming up with a good title for this question, suggestions are appreciated!
It's pretty straight forward. This is how I would do it in C++11 and above:
class Blink {
public:
enum class Sequence { Error, Active };
void setter(Sequence s) {
if (s == Sequence::Active) {
mode = 1;
} else {
mode = 0;
}
}
private:
int mode = 0;
};
Blink b;
int main() {
b.setter(Blink::Sequence::Active);
}
The main difference is that Sequence is declared publicly. Note that mode is still a private variable so there is no harm. Sequence becomes part of the public interface because it needs to be understood from outside.
The second change is that I use enum class. Yes, you could also use a plain enum that implicitely casts to the integer, but see Why is enum class preferred over plain enum?
In this simple example, I would instead use private member Sequence mode = Sequence::Error; instead of int mode = 0;.
In my computer science class I have an enum value in a header file and I'm having troubles with the get and set functions. I'm quite new to C++. This is part of my header file:
enum class SchoolType {
Elementary = 1,
Secondary = 2
};
class School : public Institution
{
public:
// There are a couple more values here
SchoolType GetSchoolType();
void SetSchoolType(SchoolType typeSchool);
};
And this is part of my .cpp file:
SchoolType GetTypeSchool()
{
return this->_typeSchool;
}
void SetTypeSchool(SchoolType typeSchool)
{
}
But 'this' brings up an error and says that 'this' may only be used inside a nonstatic member function. How can I get that function to work? My computers teacher told me that that is how I should code the get function but I still don't understand, is there something that I'm doing wrong in the header?
For the .cpp file, you should have:
SchoolType School::GetSchoolType() {
return this->_typeSchool;
}
void School::SetSchoolType(SchoolType typeSchool) {
// Insert code here...
}
Basically, in C++ you need to specify what class the function is part of (in this case, School) when defining the member functions, or else the compiler doesn't see it as being part of any class. You also need to keep your method names consistent (GetSchoolType vs GetTypeSchool).
So I have a base class A that has these functions:
virtual void DoSomething(SomeNameSpace1::EnumID ID) = 0;
virtual void DoSomething(SomeNameSpace2::EnumID ID) = 0;
virtual void DoSomething(SomeNameSpace3::EnumID ID) = 0;
I also have 2 derived classes B and C that define how these functions work. The way SomeNameSpace1::EnumID, SomeNameSpace2::EnumID and SomeNameSpace3::EnumID are defined depends on whether or not it is used in class B or class C. Thus, I have two files:
enum_defn_B.hpp:
namespace SomeNameSpace1 {
enum EnumID {
ENUM_TYPE_1 = 0 ,
ENUM_TYPE_2
}
namespace SomeNameSpace2 {
enum EnumID {
ENUM_TYPE_3 = 0 ,
ENUM_TYPE_4
}
namespace SomeNameSpace3 {
enum EnumID {
ENUM_TYPE_5 = 0 ,
ENUM_TYPE_6
}
enum_defn_C.hpp:
namespace SomeNameSpace1 {
enum EnumID {
ENUM_TYPE_7 = 0 ,
ENUM_TYPE_8
}
namespace SomeNameSpace2 {
enum EnumID {
ENUM_TYPE_9 = 0 ,
ENUM_TYPE_10
}
namespace SomeNameSpace3 {
enum EnumID {
ENUM_TYPE_11 = 0 ,
ENUM_TYPE_12
}
The problem I have now is that the base class A does not recognize the type SomeNameSpace1::EnumID, SomeNameSpace2::EnumID or SomeNameSpace3::EnumID. It also would not make sense to include either the enum_defn_b.hpp or the enum_defn_c.hpp files because they are specific to the two derived classes. What can I do in this case? I read some stuff about forward declarations but wasn't sure if that would be the correct method.
In the derived classes I would include each of their .hpp enum_defn files but what about the base class?
Are you trying to use polymorphic behavior caused by different values?
Isn't a switch-case more appropriate? It could be done also with templates, but those are a pretty advanced topics.
Anyway, may-be this explanation will give you some insights:
1) If you want to use a type, it should be declared prior to usage.
2) The derived classes have to include the declaration of the base class, and implicitly the definition of the enums.
3) If each derived class file would define its enums with already existing names in a different way, it would harm one definition rule - one of the basic concepts of C++.
A should make sense irrespective of whether or not any Bs or Cs are derived from it. What should A think of SomeNameSpaceX other than that it doesn't seem to exist?
My Goal
I have multiple functions that will return a large List of errorcodes.
Some functions will use same and distinct errorcodes of the "List of errorcodes"
for Example:
fun1() will ONLY return errorcode1 OR errorcode2 (errorcode2 is only used in this function)
fun2() will ONLY return errorcode1 OR errorcode3 (but errorcode1 is used in both functions)
The desired solution should consider the following points:
-
Have a definition what errorcode can be returned by which function
Get compile error if any function tries to return an errorcode that was not intended for this function
Whatever the function return or throws must be convertable to int (because these functions will be part of a C API)
My Approaches
So far I considered to options that use enums but the solutions do not appeal to me
Define for each function a separate enum
Define one global enum for all function
Define for each function a separate enum
enum errorcodefun1 {errorcode1=1, errorcode2=2}; // OK at least it is expressed what is expected for fun1
errorcodefun1 fun1() { };
enum errorcodefun2 {errorcode1_fun2=1, errorcode3_fun2=3 }; // minor problem: not expressing that errorcode1_fun2 is logical same as errorcode1
The more functions (which partly use same errorcode) the more code duplication I get.
Define one enum for all function
enum errorcodes {errorcode1=1, errorcode2=2, errorcode3=3};
errorcode fun1() {... } //do not like because I will get no compilation error if it returns errorcode3. Only errorcode1 and errocode2 is intended
errorcode fun2() {... }
My Question
I was thinking about writing a class that emulates the enum, but so far I see the solution that satisfies all my needs.
Do you have some suggestions or ideas how to accomplish my goal?
How about going with approach #1 but staying safe and expressing the equivalence of the enum members?
enum generic_error {
ERR_OK,
ERR_NOMEM,
ERR_IO,
ERR_GENERIC
};
enum first_error {
FIRSTERR_OK = ERR_OK,
FIRSTERR_NOMEM = ERR_NOMEM
};
enum second_error {
SECONDERR_OK = ERR_OK,
SECONDERR_IO = ERR_IO
};
int main()
{
enum first_error f = FIRSTERR_OK;
enum second_error s = SECONDERR_OK;
assert(f == s); // never fires
return 0;
}
Not that this would be particularly good practice, though... If I were you, I would really just opt to have one common error code enumeration.
Use bitmasks.
enum Code : unsigned int
{
None = 0,
SomeError= 1,
AnotherError = 2,
YetAnotherError = 4
};
unsigned int valid_error_codes_for_func1 = SomeError | YetAnotherError;
I am using fully qualified name of the enum inside a method in one of my class. But I am getting compiler warning which says "warning C4482: nonstandard extension used: enum 'Foo' used in qualified name". In C++, do we need to use enums without the qualified name? But IMO, that looks ugly.
Any thoughts?
Yes, enums don't create a new "namespace", the values in the enum are directly available in the surrounding scope. So you get:
enum sample {
SAMPLE_ONE = 1,
SAMPLE_TWO = 2
};
int main() {
std::cout << "one = " << SAMPLE_ONE << std::endl;
return 0;
}
To make it clean, replace:
enum Fruit {
ORANGE = 0,
BANANA = 1
};
with
namespace Fruit {
enum { //no enum name needed
ORANGE = 0,
BANANA = 1
};
};
...
int f = Fruit::BANANA; //No warning
While sth does answer the question, it didn't address how I've always used enums. Even though they're just more or less names for numbers, I've always used them to define types that can only have certain values.
If the enum is part of the class, then that helps consumers clearly identify an enum reference:
class Apple {
enum Variety {
Gala,
GoldenDelicious,
GrannySmith,
Fuji
}
...
};
Then consumers would be able declare instances of the enum, pass as parameters, and qualify them when referencing one of the types.
unsigned int GetCountOfApples( Apple::Variety appleVariety );
...
fujiCnt = GetCountOfApples( Apple::Fuji );
Sometimes you want an enum outside of a class or two enums in the same class, and you can do something like what Poy had. You won't be able to reference the enum type though, so just name it.
namespace Color {
enum ColorEnum {
Blue,
Red,
Black
};
Now using the enum and values would work like:
Color::ColorEnum firstColor = Color::Blue;
Color::ColorEnum secondColor = Color::Red;
if( firstColor == secondColor )
....
Now if there happens to be different enums with the same name in them, they will always be qualified with what type they are. Then you could handle what gamblor is asking about.
BananaColorEnum banCol = BananaColor::Yellow;
TomatoColorEnum tomCol = TomatoColor::Yellow;
Yes. Conceptually enum defines a type, and the possible values of that type. Even though it seems natural, to define enum foo { bar, baz }; and then refer to foo::baz is the same as referring to int::1.
namespace Company
{
typedef int Value;
enum
{
Microsoft= 0,
APPLE = 1,
};
};
namespace Fruit
{
typedef int Value;
enum
{
ORANGE = 0,
BANANA = 1,
APPLE = 2,
};
};
...
Fruit::Value f = Fruit::BANANA; //No warning
Company::Value f = Company::APPLE; //is different value then Fruit::APPLE
This works on GCC and MS compiler and Mac. And the advantage is that you can use namespace operator and pass conflicts. The little disadvantage is that instead of Fruit, you have to write Fruit::Value. it is more useful in large project when you don't know what enums are in other class.
If it is possible to use C++11 instead, it is much more simple, because the enum::namespace syntax is then possible.
The cleanest way I've found to do this is defining the enum as such
namespace Samples
{
enum Value
{
Sample1,
Sample2,
Sample3
};
}
typedef Samples::Value Sample;
Then in function and variable definitions you can use the typedef:
void Function(Sample eSample);
Sample m_eSample;
And in your .cpp file you can use the namespace to assign variables:
void Function(Sample eSample)
{
m_eSample = Samples::Sample1;
eSample = Samples::Sample2;
}
Personally, I think this is a compiler bug. I've been using C++ for lots of time. Sadly, no sample code in OP. The interpretation of an enum by the Java people was actually correct iMO. Mine, was like this ...
class Foo {
enum tMyEnum { eFirstVal = 0, eSecondVal = 1};
// ...
tMyEnum m_myVal;
};
void Foo::MyMethod() {
if(m_myVal == tMyEnum::eFirstVal) {
// ...
}
}
I also tried, Foo::tMyEnum::eFirstVal. Without the qualifiers, everything compiled.
I had the same problem and I'm not using C++ 11 yet. I much prefer fully qualified namespaces myself too.
I disabled this particular warning. I'm sure people will dislike the idea but some may be thankful..
#pragma warning( disable : 4482 )