I have 2 classes ,defined in the different namespaces :
//--==file1.hpp==--
namespace n1{
class x1 {
//.....
};
};
//--==file2.hpp==--
namespace n2{
class x1: public n1::x1{
//.....
};
};
//--== file3.hpp ==--
namespace n2 {
class x2 {
private:
n1::x1* data1_;
public:
void func(x1* data2) { data1_ = data2; }
};
};
The compilation of this fails with
error C2440: '=' : cannot convert from `'n2::x1 *' to 'n1::x1 *'`
I can`t understand what could be a problem,Since n2:x1 inherits from n1::x1...?
Thank you
Inheritance from one namespace to another namespace class, should not have any compilation error. It is just that, in the sub-class, if you have to call the method of the parent class (which is in another namespace), you should use the complete name (with namespace).
For you reference:
namespace a
{
class A1 {
public:
void testA1() {...}
};
}
namespace b
{
class B1: public class a::A1
{
public:
void testB1()
{
a::A1::testA1();
...
}
};
}
But looks like, the above problem was just been a typo issue, and has been resolved. However, to clarify on the usage, sample code shall help.
In file2.h: Include file1.h
In file3.h: Include file1.h and file2.h.
And in main include file3.h.
int main()
{
n2::x2 xx22;
n2::x1* xx11;
xx22.func(xx11);
}
This complies just fine.
Related
I'm having a compilation error using Apple's Clang 7.0 with the following friendship code, using C++11 standard. I wonder what's really wrong with it since it seems to be valid for me. I'm describing the setting and the error I'm having:
MyInterface
namespace namespace1
{
class MyInterface
{
friend class MyClass;
public:
virtual void some_method(void) = 0;
...
private:
type some_attribute;
...
}
}
MyClass::MyMethod Implementation
namespace namespace2
{
void MyClass::MyMethod(MyInterface* MyConcrete)
{
...
// MyConcrete implements MyInterface
if(MyConcrete->some_attribute == some_value) // Error*
{
...
}
...
}
}
Error
error: 'some_attribute' is a private member of 'namespace1::MyInterface'
I really expected that MyClass would have access to some_attribute in MyConcrete (which implemented MyInterface) regardless of the class access modifier. Any clues why this error is happening? Any suggestions?
Thank you!
MyClass is in namespace2. So you need to use:
friend class namespace2::MyClass;
You may also need to use forward decleration of MyClass before you define MyInterface.
Here's an example that compiles:
// forward decleration
namespace namespace2
{
class MyClass;
}
namespace namespace1
{
class MyInterface
{
friend class namespace2::MyClass; // added missing namespace
public:
virtual void some_method(void) = 0;
private:
int some_attribute;
};
}
namespace namespace2
{
class MyClass
{
void MyMethod(namespace1::MyInterface* MyConcrete)
{
if(MyConcrete->some_attribute == 1)
{
}
}
};
}
int main()
{
}
You can run it here.
friend class MyClass; in the context of ::namespace1::MyInterface refers to the class ::namespace1::MyClass, which is a different class from ::namespace2::MyClass. (That's the whole point of namespaces, right?)
Change the friend declaration to read like this:
friend class ::namespace2::MyClass;
Note that this requires that the type ::namespace2::MyClass has already been declared, so you either need to forward-declare it (namespace namespace2 { class MyClass; }) or you need to make sure that the definition is included prior to the definition of ::namespace1::MyInterface.
(See this demo.)
Here is the code -- a component class first:
// LoSComponent.h
namespace LoS {
class Component: public Ref {
public:
Component();
~Component();
};
}
and another class need a pointer of LoS::Component as parameter:
LoSStrategyPreProcessBase.h
#include "LoSComponent.h"
namespace LoS {
namespace Strategy {
namespace PreProcess {
class Base {
public:
Base(LoS::Component* losComponent)
{
this->_losComponent = losComponent;
};
~Base()
{
};
public:
LoS::Component* _losComponent;
};
}
}
}
And the code above will give me the error:
LoSStrategyPreProcessBase.h No type named 'Component' in namespace 'LoS'
Any ideas that how I can get this code to complier?
Thanks in advance .
Update 1:
I tried to replace LoS::Component to ::LoSComponent but is still getting the same error:
Update 2:
I created a simple project with 2 simple class and I found that the problem seem to be caused in header file inclusion.
The code complier && link OK:
LoSComponent.h
#ifndef LoSComponent_h
#define LoSComponent_h
namespace LoS {
class Component {
public:
Component();
~Component();
};
}
#endif /* LoSComponent_h */
And :
#ifndef LoSBase_h
#define LoSBase_h
#include "LoSComponent.h"
namespace LoS {
namespace Stragergy {
class Base {
public:
Base(LoS::Component* los){
this->_los = los;
};
~Base();
private:
LoS::Component* _los;
};
}
}
#endif /* LoSBase_h */
As you can see I can use LoS::Component in LoSBase.h with no error.
Then I tried to change the LoSComponent.h :
#ifndef LoSComponent_h
#define LoSComponent_h
#include "LoSBase.h"
namespace LoS {
class Component {
public:
Component();
~Component();
private:
LoS::Stragergy::Base* _base;
};
}
#endif /* LoSComponent_h */
As you can see I added a
#include "LoSBase.h"
and
LoS::Stragergy::Base* _base;
and this time it fails with an error:
LoSComponent.h:23:14: error: no member named 'Stragergy' in namespace 'LoS'
LoS::Stragergy::Base* _base;
~~~~~^
LoSBase.h:20:23: error: no type named 'Component' in namespace 'LoS'
Base(LoS::Component* los){
~~~~~^
Change Base(LoS::Component* losComponent) to Base(::LoS::Component* losComponent).
:: before namespace, class or function tells compiler to look for namespace/class/function in global namespace
I currently have the following two classes
class TOrder
{
public:
private:
.......
};
Now my other class is :
#include "TOrder.h"
namespace namespaceA
{
namespace namespaceB
{
class OrderDis
{
private:
TOrder* frmPointer;
.....
};
}
}
The above works fine the problem starts when I use an object of OrderDis in TOrder as such
#include <QMainWindow>
#include "OrderDis" //Added - Creates Problem
class TimedOrder
{
public:
.......
};
Any suggestion on how I could use forward declaration to resolve my issue ?
You could forward OrderDispatcher in TimeOrder.h
namespaceA
{
namespaceB
{
class OrderDispatcher;
}
}
class TimedOrder
{
//...
};
The forward declaration can be written as:
namespace A{ namespace B{ class OrderDispatcher; } }
As you only use a pointer to TimedOrder in the OrderDispatcher class, it can be solved by simply not including TimedOrder.h in the OrderDispatch.h file. Instead just declare the TimedOrder class:
class TimedOrder;
No need to muck about with namespaces and such then.
Note: You can't declare it in any of the namespaces, declare it instead where you now do your #include.
The error I get is "No member named detail in namespace ChessGame. Here is the relevant code
//ChessPiece.h
namespace ChessGame
{
class ChessBoard;
namespace detail
{
class IChessPieceEnums{
public:
enum PieceType{PAWN, KNIGHT, BISHOP, ROOK, QUEEN, KING};
enum PieceDirection{ UP = 1 , DOWN = -1};
enum PieceId{ WHITE_PIECE_ID, BLACK_PIECE_ID };
};
}
//represents an abstract chess piece interface
class IChessPiece : public detail::IChessPieceEnums
{
public:
///...
}
} // end namespace
//GameBoard.h
#include "ChessPiece.h"
namespace ChessGame
{
class IChessPiece;
class ChessBoard
{
public:
/*********ERROR OCCURS ON THIS FUNCTION************/
bool isOccupiedWithEnemy(int row, int col,const ChessGame::detail::IChessPieceEnums::PieceId& pieceId);
}
}
Any idea guys?
EDIT: Another minimal example :
//Piece.h
#ifndef TestProject_C___Piece_h
#define TestProject_C___Piece_h
#include "Board.h"
namespace Foo {
namespace detail{
struct PieceEnums{
enum PieceID{ ID1, ID2 };
};
}
class Board;
class Piece{
public:
void foo(Board& b)const;
};
}
#endif
//board.h
#ifndef TestProject_C___Board_h
#define TestProject_C___Board_h
#include "Piece.h"
namespace Foo {
class Piece;
class Board{
bool isOcc(int x, int y,const detail::PieceEnums::PieceID pid)const;
};
}
#endif
And the error is 'Use of undeclared identifier detail
Note that this is across multiple files, so maybe its a problem with linkage?
To specify the desired name directly, say either detail::IChessPieceEnums::PieceId or ::ChessGame::detail::IChessPieceEnums::PieceId, but preferably the former. However, your present syntax is actually fine, too, since search resumes in the global namespace if a name can't be found.
Ok found a solution. The solution is to put the namespace detail in its own file called detail.h. That way, piece.h and board.h needs to include details.h to use it. That worked.
And the problem with the original post is that there is a circular reference. That is causing trouble somehow. Would love an explanation.
i got a compile error which i do not understand.
i have a h/cpp file combination that does not contain a class but just defines some utility functions. when i try to use a struct that is defined in another class i get the error:
error C2027: use of undefined type 'B::C'
so, stripped down to the problem, the h-file looks like this
namespace A {
void foo(B::C::SStruct const & Var);
}
the definition of SStruct is in a class which is in another h-file, that is of course included.
namespace B {
class C {
public:
struct SStruct { };
};
}
the strange thing is, i can use this struct in other classes fine, it just seems to be related to this one h-file which contains just utility functions.
what am i missing here?
thanks!
After correcting missing semicolons etc. this compiles:
namespace B {
class C {
public:
struct SStruct { };
};
}
namespace A {
void foo(B::C::SStruct const & Var);
}
Obviously, if the order of the two namespaces were switched, this would not work. Possibly you are #including your headers in the wrong order. If this is the error, that's bad design - you should not allow header order to matter in your code.
I assume you meant "class C", not "Class C".
struct SStruct is private to class C (private being the default visibility of class members).
As such, it is not visible outside class C and its friends, which does not include A::foo().
Class C {
struct SStruct { };
}
==>
class C {
public:
struct SStruct { };
};
Your class is missing a semicolon after the definition. It should be:
namespace B {
class C {
public:
struct SStruct { };
}; // <=== Here
}