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.
Related
I am writing a class C which has an inner class T, and I'd like the details of T hidden as an internal implementation of C. Methods in C are all using pointers to T. This is of course possible as:
// In header
class C {
public:
class T;
T* f();
void g(T*);
};
// In .cpp
class C::T { /* details here */ };
Now my question is, how can I define C::T as a type alias of another one, in .cpp file. The following doesn't compile at all, but it illustrates what I want to do:
// Outside the class C
using C::T = std::string;
Is there any workaround to this, while maintaining the goal, i.e. hide the detail of C::T?
As others pointed out, it cannot be done. This is my suggestion:
// .h
class C {
public:
struct T;
T* f();
void g(T*);
};
// .cpp
struct C::T
{
IMPL_TYPE data;
//If one is carefull with lifetimes this can almost in any context act as IMPL_TYPE.
//And if necessary, the data member can be accessed.
operator IMPL_TYPE&(){return data};
}
You cannot, because the forward declaration class T; within class C declares a class type whose True Name is C::T, and is therefore not identical to the type whose True Name is std::basic_string<...>.
You might consider the following:
// C.h
#include "internal/T.h"
namespace foo {
class C {
public:
using T = internal::T;
// ...
};
}
// internal/T.h
namespace foo { namespace internal {
using T = std::string;
}}
The closest you can come to this would be to have your t derive from string:
class C::T : public std::string { ... };
T can never be truly hidden or redefined to be a type alias in a different .cpp file.
The following round about method should work for your needs.
class C
{
public:
// Use a base class for just the pointers.
struct TBase
{
virtual ~TBase() {}
};
TBase* f();
void g(TBase*);
// Allow client code to define a concrete type using a template parameter.
template <typename Data> struct T : TBase
{
Data data;
};
};
Then, in a .cpp file, use:
using Type = C::T<std::string>;
Type* obj = new Type;
obj->data = "Some string";
C c;
c.g(obj);
TBase* ptr = c.f();
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.
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.
Ok here is the situation.
//foo.h
struct A1{
struct A2{};
};
//bar.h
#include "MyString.h"
class A2; //note, not including foo.h
TEMPLATE_INSTIANTIATE_MAP_OF_TYPE(String,A2*); //assume compiler doesn't do this
Is it possible to make the above situation work? I try to create a MyMap<String,A1::A2*> m; but the compilers throws undefined reference errors. Is it possible to make the above work without having bar.h import foo.h?
Sadly, it isn't. Nested classes can only be declared inside a class definition.
Here is a way to declare nested classes outside a class definition.
class Logic is the outer class. LogicImp is the forward declared struct.
class Logic
{
public:
Logic();
~Logic();
private:
struct LogicImp;
std::unique_ptr<LogicImp> limp_;
};
struct Logic::LogicImp
{
int nLogical_;
};
Logic::Logic():limp_(new LogicImp())
{
}
Logic::~Logic()
{
}
Right now, my project has two classes and a main. Since the two classes inherit from each other, they are both using forward declarations. In the first object, right underneath the #include statement, I initialize two enums, before the class definition. I can use both enums just fine inside that class. However, if I try to use those enums in the other class, which inherits from the first one, I get an error saying the enum has not been declared. If I try to redefine the enum in the second class, I get a redefinition error.
I have even tried using a trick I just read about, and putting each enum in its own namespace; that didn't change anything.
Here's an example:
#ifndef CLASSONE_H
#define CLASSONE_H
namespace Player
{
enum Enum
{
One,
Two,
};
}
#endif
Then inside the second class, I attempt to use the enum declared earlier:
void AddPlayer(Player::Enum playerNumber);
and instead get an error saying 'Player' has not been declared.
I'm not sure what issue you are having without seeing your code, but this compiles:
enum OutsideEnum
{
OE_1,
OE_2,
};
namespace ns
{
enum NSEnum
{
NE_1,
NE_2,
};
}
class Base
{
public:
enum BaseEnum
{
BE_1,
BE_2,
};
void BaseFunc();
};
class Derived
{
public:
enum DerivedEnum
{
DE_1,
DE_2,
};
void DerivedFunc();
};
void Base::BaseFunc()
{
BaseEnum be = BE_1;
Derived::DerivedEnum de = Derived::DE_1;
OutsideEnum oe = OE_1;
ns::NEEnum ne = ns::NE_1;
}
void Derived::DerivedFunc()
{
Base::BaseEnum be = Base::BE_1;
DerivedEnum de = DE_1;
OutsideEnum oe = OE_1;
ns::NEEnum ne = ns::NE_1;
}
int main()
{
Base::BaseEnum be = Base::BE_1;
Derived::DerivedEnum de = Derived::DE_1;
OutsideEnum oe = OE_1;
ns::NEEnum ne = ns::NE_1;
}
Two things to watch for with enums defined inside a class definition:
Make sure it's declared public if you want it publicly available.
When referencing it from anywhere other than the class it's defined in, use the class name to qualify the name of the enum and the values.
EDIT:
Ok, the problem has nothing to do with enums, but rather order of inclusion, when you have a base class and a derived class, only the derived class needs to know about the base class:
Base class header:
#ifndef BASE_H
#define BASE_H
enum BaseEnum
{
};
class Base
{
};
#endif
Derived class header:
#ifndef DERIVED_H
#define DERIVED_H
#include "Base.h"
class Derived
{
void Func(BaseEnum be);
};
#endif