2016-04-05 2 views
1

Gibt es irgendwelche gute Methoden zum Trennen einer verschachtelten Datentypdefinition aus dem Container und in eine andere Datei?Definieren Sie vorwärts deklarierte verschachtelte Struktur/Klasse/enum in einer anderen Datei für Ordentlichkeit

Ich habe eine Klasse mit mehreren verschachtelten Strukturen/Klasse enums in einer Kopfzeile definiert, die ziemlich lang sein kann.

MyClass.h

#ifndef MYCLASS_H_ 
#define MYCLASS_H_ 
#include <stdint.h> 

namespace my_namespace{ 

class MyClass { 

public: 

    enum class NestedEnumClass { 
    VALUE1, VALUE2, VALUE3 
    }; 

    struct NestedStruct { 
    float a; 
    float b; 
    uint_fast16_t c; 
    }; 

    struct SomeOtherNestedStruct { 
    float a; 
    float b; 
    uint_fast16_t c; 
    }; 

    struct AnotherNestedStruct { 
    float a; 
    float b; 
    uint_fast16_t c; 
    }; 

private: 
    struct CombinedStruct { 
    NestedStruct a; 
    NestedStruct b; 
    NestedStruct c; 
    AnotherNestedStruct d; 
    NestedEnumClass e; 
    }; 

    uint8_t pin; 
    CombinedStruct data_; 

public: 
    MyClass(); 
    NestedEnumClass someMethod(NestedStruct nestedStruct); 

}; // MyClass class. 

} // my_namespace namespace. 

#endif /* MYCLASS_H_ */ 

Um die Header kürzer/sauberere zu machen, war ich zunächst von uns denken, die Datentypen in der MyClass Definition-Header-Datei deklarieren und die Definition der Datentypen in ein separate Quelle, die die Header-Datei enthält.

Allerdings beschwert sich der Compiler zu Recht über einen unvollständigen Typ, wenn ich versuche, einen der Datentypen zu instanziieren.

Ich glaube, ich es in-line umfassen könnte, aber es scheint schrecklich:
MyClass_DataTypes.inc

public: 
enum class NestedEnumClass { 
    VALUE1, VALUE2, VALUE3 
    }; 

struct NestedStruct{ 
    float a; 
    float b; 
    uint_fast16_t c; 
}; 

struct SomeOtherNestedStruct { 
    float a; 
    float b; 
    uint_fast16_t c; 
}; 

struct AnotherNestedStruct { 
    float a; 
    float b; 
    uint_fast16_t c; 
    }; 

private: 
struct CombinedStruct { 
    NestedStruct a; 
    NestedStruct b; 
    NestedStruct c; 
    AnotherNestedStruct d; 
    NestedEnumClass e; 
}; 

Modified MyClass.h

#ifndef MYCLASS_H_ 
#define MYCLASS_H_ 
#include <stdint.h> 

namespace my_namespace{ 

class MyClass { 

#include "MyClass_DataTypes.inc" // In-line include. 

private: 
    uint8_t pin; 
    CombinedStruct data_; 

public: 
    MyClass(){}; 
    NestedEnumClass someMethod(NestedStruct nestedStruct); 

}; // MyClass class. 

} // my_namespace namespace. 

#endif /* MYCLASS_H_ */ 

Auch meine IDE (Eclipse) ist nicht schlau genug, um das Include für die On-The-Fly-Code-Überprüfung zu finden, also müsste ich sie in der Klassendefinition weiterleiten obwohl es ohne sie gut kompiliert.

+0

IMHO ist dies eine schreckliche Lösung –

+0

@RichardHodges Meinen Sie die Definition von der Deklaration trennen? –

+0

Die geschachtelte Klasse ist ein starker Hinweis darauf, dass diese Klassen privat sein sollten. Andernfalls müssen sie nicht verschachtelt werden. – user3528438

Antwort

3

So würde ich wahrscheinlich näher kommen.

Synopsis:

  1. anderen Namespace für die inneren Klassen erstellen

  2. Import die Namen der inneren Klassen in meiner äußeren Klasse Schnittstelle nach Bedarf

Etwas wie folgt aus:

#ifndef MYCLASS_IMPL_H_ 
#define MYCLASS_IMPL_H_ 

#include <cstdint> 

namespace my_namespace { 
    namespace MyClassImpl { 

     enum class NestedEnumClass { 
      VALUE1, VALUE2, VALUE3 
     }; 

     struct NestedStruct { 
      float a; 
      float b; 
      uint_fast16_t c; 
     }; 

     struct SomeOtherNestedStruct { 
      float a; 
      float b; 
      uint_fast16_t c; 
     }; 

     struct AnotherNestedStruct { 
      float a; 
      float b; 
      uint_fast16_t c; 
     }; 

    } 
} 
#endif 

#ifndef MYCLASS_H_ 
#define MYCLASS_H_ 
#include <stdint.h> 

namespace my_namespace{ 

    class MyClass { 

    public: 
     using NestedEnumClass = MyClassImpl::NestedEnumClass; 
     using NestedStruct = MyClassImpl::NestedStruct; 
     using SomeOtherNestedStruct = MyClassImpl::SomeOtherNestedStruct; 
     using AnotherNestedStruct = MyClassImpl::AnotherNestedStruct; 


    private: 
     struct CombinedStruct { 
      NestedStruct a; 
      NestedStruct b; 
      NestedStruct c; 
      AnotherNestedStruct d; 
      NestedEnumClass e; 
     }; 

     uint8_t pin; 
     CombinedStruct data_; 

    public: 
     MyClass(); 
     NestedEnumClass someMethod(NestedStruct nestedStruct); 

    }; // MyClass class. 

} // my_namespace namespace. 
+0

Ich mag es! Das ist eine großartige Lösung. Sehr geschätzt –

+0

@ mattb5906 glücklich zu helfen. Im Gegenzug bin ich froh, dass du den Quellcode sauber halten willst :-) –