In C ++, how can I avoid the #include header file when I need to use an enumeration?

In my C ++ header files, I try to use forward declarations (MyClass; class) instead of #include the class header, as recommended by many C ++ coding standards (the Google C ++ style guide is one thing).

Unfortunately, when I enter the listings, I can no longer make a direct announcement. Like this:

//// myclass1.hpp ////

class MyClass1
{
    enum MyEnum1
    {
        Enum_A, Enum_B, Enum_C
    };
};

//// myclass2.hpp ////

// I want to avoid this
#include "myclass1.hpp"

// I'd prefer to do this (forward declaration)
class MyClass1;

class MyClass2
{
    // This is o.k.: I only need to forward declare MyClass1
    MyClass1* ptr;

    // This forces me to #include, but I don't want to!
    void func( MyClass1::MyEnum1 e );
};

The best solution I can think of is to replace the enumerations with member constants:

//// myclass1.hpp  ////

MyClass1
{
    static const int Enum_A;
    static const int Enum_B;
    static const int Enum_C;
};

//// myclass1.cpp ////

const int Enum_A = 1;
const int Enum_B = 2;
const int Enum_C = 3;

In this case, the solution seems worse than the problem.

I am currently reviewing a large-scale software design in C ++ (Lakos) and working effectively with legacy code (Feathers) for dependency breaking methods, but have not yet found a good solution.

+5
8

- - .

, #include ? , # . " " - .

+6

. , enum ?

: , , , (AFAIK) . , . , , , , !

+12

. , .

enum , . , .

+4

++ 0x . GCC 4.4.0 CodeGear ++ Builder 2009 .

enum-, , (, ) Boost.Enum Boost Vault at . Boost.Enums , .

( ) ( ++ 0x).

+4

"" . :

// enum.h
struct MyClass1 { enum e { cE1, cE2, cELast }; };

// algo.h
// precondition: tEnum contains enumerate type e
template< typename tEnum > typename tEnum::e get_second() { 
    return static_cast<typename tEnum::e>(1); 
}

// myclass1.h

// myclass.h
template< typename tClass1 >
class MyClass2
{
    tClass1 * ptr;
    void func( tClass1::e e );
};
// main.cpp
#include "enum.h"
#include "algo.h"
int main(){ return get_second<Enum>(); }
+2

( ), , . .

, . , , , , .

+1

C++. . (pdf). , , !

0

- , int enum. , . , :

// in class1.h
class Class1 {
public:
    enum Blah {
       kFirstBlah, // this is always first
       eOne = kFirstBlah,
       ...
       kLastBlah // this is always last
    };
};

// in checks.h
#include <stdexcept>
namespace check {
template <typename T, typename U>
U bounds(U lower, T value, U upper) {
    U castValue = static_cast<U>(value);
    if (castValue < lower || castValue >= upper) {
        throw std::domain_error("check::bounds");
    }
    return castValue;
}
} // end check namespace

// in class2.h
class Class2 {
public:
    void func(int blah);
};

// in class2.cpp
#include "class2.h"
#include "class1.h"
#include "checks.h"

void Class2::func(int blah) {
    Class1::Blah blah_;
    blah_ = check::bounds(Class1::kFirstBlah, blah, Class1::kLastBlah);
}

, , , . , check, , , enum .

The caveat is that you need to make an effort to write code-exclusive code, which I recommend regardless of whether you take this approach or not;)

0
source

All Articles