How to make a function that receives an enum - c++

class Shapemaker
{
public:
static Shape * shapeCreate(CDrawView::shape sh);
};
My enum on my CDrawView class is
enum shape{line, rect, elli};
shape current_shape;
when i call Shapemaker::shapeCreate(current_shape) on I get error c2653CDrawView : is not a class or namespace name on shapemaker.h

This is probably the most plain thing to do:
class Shapemaker{
public:
enum Color { //your colors here }
};
class Otherclass{
void fun(Shapemaker::Color);
};
Now if your compiler does not recognize Shapemaker as a class name, that makes me think you didn't include its header file before declaring Otherclass.

If it's an enum member of the other class, then you can reference it as nameoftheClass::Color, but it'd have to be publicly-visible:
void function(nameoftheClass:Color input);

Say you have as follows:
class C {
public:
enum E {
HERP,
DERP
};
};
A function taking that enum would look like:
void foo(C::E e) {
// do stuff with e
}

It's all a matter of namespace in the end. Have a look at the answers to this question too, definitively you must not use the keyword enum in the function's parameter list, use directly the enum name with the appropriate namespace.
namespaces for enum types - best practices

i tried to pass the color variable enum, but it gives me a compile error saying that the "nameoftheclass" is not a class or namespace
You need to have a declaration placed before you use it, meaning you need proper header files:
MyClass.h
class MyClass {
public:
enum Color {
Red,
Green,
Blue
};
};
MyOtherClass.h
#include "MyClass.h" // This is required.
// Now you can use MyClass::Color freely.

Related

C++ enum class with constructor

In Java, you can write a constructor for an enum, e.g.
private MyEnum(String name, int val) {
...
}
And then you can write:
public enum MyEnum {
FIRST("A", 10), SECOND("B", 20), THIRD("C", 30);
private MyEnum(String name, int val) {
...
}
}
Is there any way you can do a similar thing for a C++ enum class?
No, C and C++ enums are just a bunch of constants grouped together. C++ enum classes are the same, but to access them you need to add the name of the enum class as a "namespace".
#pragma once
#include <afxwin.h>
#include "winnt.h"
#include "winuser.h"
/// <summary>
// define Style Constants
/// </summary>
enum IS_STYLES {
TB_TEXT_DEFAULT = 0,
TB_TEXT_DOUBLE = 1,
TB_TEXT_INTEGER = 2,
TB_TEXT_CAPTION_ABOVE = 4,
TB_TEXT_CAPTION_LEFT = 8
};
class CTextBox
{
public:
IS_STYLES mStyle;
CString mString;
CTextBox();
CTextBox(
CString string,
IS_STYLES style
);
};
#include "CTextBox.h"
CTextBox::CTextBox(
CString string,
IS_STYLES Style)
:mStyle(Style),mString(string) //init list
{
// body
}
#pragma once
#include <afxwin.h>
#include "CTextBox.h"
class CMainFrame : public CFrameWnd
{
private:
CTextBox mLength; // member objects
IS_STYLES mStyle;
protected:
public:
CObList myBoxes;
CMainFrame(); // Constructor
};
#include "CMainFrame.h"
#include "CTextBox.h"
CMainFrame::CMainFrame() // CMainFrame Constructor
{
/* Create a box that's comprised of an enum and string
CTextBox's constructor
*/
CTextBox box = CTextBox(IS_STYLES(TB_TEXT_DOUBLE|TB_TEXT_CAPTION_LEFT),
"Hello World");
myBoxes.AddHead((CObject*)box); // add box to a CObList collection.
};
Yes,you can! Follow below precisely:
declare the enum list (outside of the class)but in the same namespace and naturally give it a name.
in the .h file declare a class with a member value with a type of the defined enum, its name.
also in the .h file create a class overloaded Constructor who's signature includes having the enum type with a default value(also an enum), and must be at the end of the signature and Initialization list.
in the cpp, use the overloaded Constructor that includes the enum, here use the enum value of your choice, from the declared enum list.
also in the cpp, in the Class implementation
list, set the Class member's enum value to the enum declared your Constructor's signature(your chosen value).
Enjoy...
Not sure how you'd use "more" than 1 value in the Initialization List which would allow you to then be able to use bitwise and, and bitwise or decision making in your Derived / Instantiated Class.

Forward Declaration of enum in a class ?

I have two Abstract Class wich own each other a pointer of the other one. I need to use in one of them an enum of the other Class, like show the exemple.
AFoo is holding ABar, and ABar need a pointer to AFoo to update some data and also a member function that gonna use the AFoo enum.
I remember having this problem once but not with enum and i ended up doing inline declaration.
I could do a nested class, but is there another way to avoid that?
AFoo.hpp :
#include ...
class AFoo;
enum AFoo::poo; --> not possible
#include "ABar.hpp"
class AFoo {
public:
...
virtual void func() = O;
enum poo {
H,
I,
...
}
protected:
ABar *bar_;
};
ABar.hpp
#include ...
class Abar;
#include "AFoo.hpp"
class ABar {
public:
...
virtual AFoo::poo doing_some_stuff() = 0; --> Here is my problem (if i replace the return type with basic type i have no compilation problem)
protected:
AFoo *foo_;
};
In AFoo.hpp, don't include ABar.hpp, only forward declare the class:
class ABar;
Also, in ABar.hpp, include AFoo.hpp and don't forward ABar or AFoo.
In AFoo.hpp, remove
enum AFoo::poo; --> not possible
and replace
#include "ABar.hpp"
with
class ABar;
Also, your enum declaration is missing a semicolon.

Why am I getting this 'enum' is not a class or a namespace error?

I need call a method with this signature in my Manager class:
void createPlayer(Player& player, PlayerType& playerType);
I have a Player defined like so:
using namespace std;
enum PlayerType { FORWARD, DEFENSEMAN, GOALIE };
class Player {
public:
Player();
void setType(PlayerType);
private:
PlayerType type;
};
This is how I try to call the method in main ...
#include "Player.h"
#include "Manager.h"
int main() {
Manager manager;
Player player;
PlayerType t = PlayerType::FORWARD;
manager.createPlayer(player, t);
return 0;
}
... but it fails to compile with this error:
Main.cc: In function ‘int main()’:
Main.cc:12:18: error: ‘PlayerType’ is not a class or namespace
Any ideas? Note: I cannot change the signature of the createPlayer method.
enum doesn´t create a namespace.
Therefor PlayerType t = PlayerType::FORWARD; should be changed to:
PlayerType t = FORWARD;
Notice that c++11 introduce enum classes, which have a namespace. Beside this MSVC has an extension which treats (regular) enums like they have namespace. So your code should actually work with MSVC.
Unfortunately enum by default doesn't create an enum namespace. So when declaring:
enum PlayerType { FORWARD, DEFENSEMAN, GOALIE };
you'll have to use it like this:
auto x = FORWARD;
Thankfully, though, C++11 introduced enum class or enum struct to solve this issue:
enum class PlayerType { FORWARD, DEFENSEMAN, GOALIE };
You'll then be able to access it like you did:
auto x = PlayerType::FORWARD;
Your error seems to be in this line:
PlayerType t = PlayerType::FORWARD;
As far as I know, the scope resolution operator (::) is not valid on regular C++98 enums unless your compiler supports them through non-standard extensions (like Visual Studio). Therefore you can't use it to reference an specific value from the enumerator.
Also, C++98 enums have the problem of polluting the namespace in which they are defined which can lead to name clash. Luckily C++11 solved this introducing the enum class. For more information check Stroustrup's FAQ: http://www.stroustrup.com/C++11FAQ.html#enum
add a static function say getForward:
class Player {
public:
Player();
void setType(PlayerType);
static PlayerType getForward {
return FORWARD;
}
private:
PlayerType type;
};
Then use it in main:
manager.createPlayer(player, Player::getForward());
This should work.

is it possible to nest to class existing enum

I have enum in some header file. Is it possible to nest to the class existing enum?
Explanation:
some headerfile.h:
enum someEnum
{
someValue
/*other values*/
};
other header:
#include "headerfile.h"
class someClass
{
public:
//using enum someEnum; //don't work as I want
};
I want that someValue will be accesible as
someClass::someValue
So my question is it possible?
You can nest that enum definition:
class someClass {
public:
enum someEnum {
someValue
};
};
Then you can access this enumerations just like the way you wanted:
someClass::someEnum X = someClass::someValue;
If, however, what you wanted was to create a member variable typed someEnum, you can do it either by just supplying someEnum as a type, or nesting the enumeration and putting the variable name before the semicolon.
well one way would be to do this:
class someClass
{
public:
#include "headerfile.h"
//using enum someEnum; //don't work as I want
};
not pretty but works.
You could try to include the library inside the class definition.

typedef'ing an enum does not make the enum-values visible

I have a class in which I have an enumeration, defined like this:
class X
{
public:
enum Direction {DIR_LEFT, DIR_RIGHT};
};
Now I want this enumeration to be reused in another class, like this:
class Y
{
public:
typedef X::Direction Direction;
};
As expected, using Y::Direction works correctly, e.g.:
void myFunction (Y::Direction dir)
{
}
But the values within the enumeration does not seem to be 'copied' together with the typedef. If I write the following, I get compilation errors:
myFunction (Y::DIR_LEFT);
Instead, I have to refer to the original place of the enumeration again, like this:
myFunction (X::DIR_LEFT);
Which defeats my purpose of typdefing the enumeration.
The only solution I see is to move the enumeration out of class X, and putting it in another class (e.g. MyEnums), so it can be reused by X and Y (although they should still use MyEnums::DIR_LEFT and MyEnums::DIR_RIGHT), but at least the code does not depend on class X anymore.
Why are the enumeration values itself no exposed via the typedef?
Are there any other patterns to manage enumerations in different classes?
Unfortunately C++ doesn't introduce a new scope with an enum although C++0x is improving things.
Practically this means that you can't typedef an enum and get the enumerated values as well.
What you can do is use a nested struct with the name you want for the enum and typedef THAT.
class X
{
public:
struct Direction { enum EnumType {LEFT, RIGHT}; };
};
class Y
{
public:
typedef X::Direction Direction;
};
Now you can do:
myFunction (Y::Direction::LEFT);
The purpose of the nested struct is to create a "fake" scope to holld both the enum name and its values.
Here is my understanding of how enums work in C++. (Or at least my observed behaviour of enums in Microsoft Visual C++.)
The enum keyword does not create a scope the same way that classes do.
The full name then for your enum 'Direction', is X::Direction. The values within that enum are still part of the class scope, so they are X::DIR_LEFT and X::DIR_RIGHT.
When you typedef the enum in another class, this does not change the scope of the values of the enum.
I suggest you put the enum inside a namespace in a header file if you want to share it in multiple locations.
If you want the enum values to be members of both classes, the
solution is to define a separate class with the enum, and
inherit from it, e.g.:
class MyEnums
{
protected:
~MyEnums() {} // Prevent delete through pointer to this class
public:
enum Direction
{
DIR_LEFT,
DIR_RIGHT
};
};
class X : public MyEnums
{
// ...
};
class Y : public MyEnums
{
// ...
};
Users will see X::Direction, X::DIR_LEFT and Y::Direction,
Y::DIR_LEFT. Of course, they'll still be able to pass
a Y::DIR_LEFT to a function expecting an X::Direction; to
prevent that, make MyEnums a template, with the derived class as
the template argument.
Anything shared by more than one class should be factored outside of the classes and perhaps into a parent class.
direction.hpp:
#ifndef DIRECTION_HPP
enum Direction {DIR_LEFT, DIR_RIGHT};
#endif
x.hpp:
#ifndef X_HPP
#include "direction.hpp"
class X
{
Direction dir;
};
#endif // X_HPP
y.hpp
#ifndef Y_HPP
#include "direction.hpp"
class Y
{
Direction dir;
};
#endif // Y_HPP
If the original declaration:
class X
{
public:
enum Direction {DIR_LEFT, DIR_RIGHT};
};
is embedded in a large legacy code-base, then we might want a solution that does not change any existing uses of X::Direction. In that case, the rather ugly:
class Y
{
public:
typedef enum X::Direction Direction;
static const enum X::Direction DIR_LEFT = X:DIR_LEFT;
static const enum X::Direction DIR_RIGHT = X:DIR_RIGHT;
}
works...
Definitely not recommended for new code, however!