I stuck at defining a static pointer inside one of my class which is pointing to another class
here is the schema of what I've done :
#busineslogic.h
class BussinesLogic {
private :
static Samenamespace::otherclass_DataLogic::clsDL *DL;
};
#busineslogic.cpp
samenamespace {
businessnamespace{
clsBL{
Samenamespace::businessnamespace::clsBL *Samenamespace::businessnamespace::clsBL::DL;
}
}
}
so with above definition I'll get error every time I compile the code , I've tried several other ways to overcome this problem but the face of the errors gonna change not the whole problem.
I want to know how can I access to another class from my class in such a static way I mean something like above example , how should I change my code ? or should add something extra?
// header:
#include <other/b.hpp>
namespace example {
struct A {
static other::B* name;
};
}
// implementation: (.cpp)
namespace example {
other::B* A::name;
}
Edit: With the cleanup of the question, it looks like B and A are in the same namespace, which would simplify the example:
// header:
#include <example/b.hpp>
namespace example {
struct A {
static B* name;
};
}
// implementation: (.cpp)
namespace example {
B* A::name;
}
Related
I have a PieceStrategy class:
#include "QueenStrategy.cpp"
class PieceStrategy {
void promoteToQueen() {
this = new QueenStrategy();
}
}
And I have a QueenStrategy class which inherits from it:
#include "PieceStrategy.cpp"
class QueenStrategy : public PieceStrategy {}
Now arises the circular includes problem. But in this case, I cannot use forward declaration.
What should I do?
You should not include cpp files, but headers
You must not assign to this
Choose another design. You should not try to modify the strategy but select another one for the actual object, that uses that strategy.
piece.hpp
#include "strategy.hpp"
class Piece
{
std::unique_ptr<Strategy> strategy;
public:
static Piece Pawn();
void PromoteToQueen();
};
piece.cpp
#include "pawn.hpp"
#include "queen.hpp"
Piece Piece::Pawn()
{
Piece p;
p.strategy = std::make_unique<PawnStrategy>();
return p;
}
void Piece::PromoteToQueen()
{
strategy = std::make_unique<QueenStrategy>();
}
I am jumping through hoops to reduce inheritance.
I read one similar question here. It shows how the issue can be resolved using a base class. I try to loose inheritance, so I am looking for something different - more along the lines of annotation.
I create and compile a template class with one specialisation (normal). The method that requires the template is in the header (Mixer.hpp). The method that does not require the template is in the cpp file (Mixer.cpp). When compiled into a static library, the cpp part only gets compiled as one specialisation (Mixer<normal>). The compiler does not know about (awsome) at that time. Importing the resulting static library into another project and attempting to create a different generic (awsome) class results in a linker error because obviously the library does not contain that method identifier (Mixer<awesome>::noTemplateInvolved). However the code for the normal implementation is as good as any so really the linker could just link to the existing source of the other template version (Mixer<?dontcare?>::noTemplateInvolved). All that the compiler has to do is to mark it appropriately for the linker.
Here is source code that results in a linker error:
//Target compiled to Provider.lib
//Mixer.hpp
#pragma once
#include <iostream>
using namespace std;
struct normal { static void log() { cout << "normal\n"; } };
template<typename output = normal>
class Mixer
{
public:
void callingTemplate();
void noTemplateInvolved();
};
template<typename output>
void Mixer<output>::callingTemplate() { output::log(); }
//Mixer.cpp
#include "Mixer.hpp"
void Mixer<>::noTemplateInvolved()
{
cout << "noTemplateInvolved\n";
}
//Target Compiled to User.exe
//This target imports Provider.lib
#include <Provider\Mixer.hpp>
#pragma comment(lib, "Provider.lib")
struct awsome { static void log() { cout << "awsome\n"; } };
int main()
{
Mixer<> n;
n.callingTemplate();
n.noTemplateInvolved();
Mixer<awsome> a;
a.callingTemplate();
a.noTemplateInvolved(); //linker error here
return 0;
}
The class Mixer<awsome> can link to the method callingTemplate because its definition is in the header and the compiler creates that function. At User.exe compile time the definition of noTemplateInvolved is hidden from the compiler. The compiler can not create that method and linking has to fail.
There are three solutions that I am aware of.
move the definition of noTemplateInvolved to the header.
include the cpp file
inherit from a baseclass
I am looking for another solution. The body of noTemplateInvolved really has nothing to do with the template. I would like to annotate the method in the header. I want the compiler to know it should always use the same base implementation regardless of the template.
Is that at all possible?
EDIT: Annotated that boring paragraph at the beginning a bit.
The answer turns out to be a base class as suggested in the comments. One of the reasons I wanted a base class is that I did not want to refactor. Refactoring using a base class is actually really simple.
Rename the original class to original_base.
Inherit from original_template inherits from original_base. Make sure to copy the contructor and pass through all the arguments to the base class.
The statement using original = original_template<your default case here> ensures that no other source code has to be modified just yet.
Applied to the example above I ended up doing something like this:
//Target compiled to Provider.lib
//Mixer.hpp
#pragma once
#include <iostream>
using namespace std;
struct normal { static void log() { cout << "normal\n"; } };
class Mixer_Base
{
private:
int mixcount;
public:
Mixer_Base(int count);
void noTemplateInvolved();
};
template<typename output = normal>
class Mixer_tempalte : public Mixer_Base
{
public:
Mixer_tempalte(int count) : Mixer_Base(count)
{}
void callingTemplate();
};
template<typename output>
void Mixer_tempalte<output>::callingTemplate()
{
output::log();
}
using Mixer = Mixer_tempalte<>;
//Mixer.cpp
#include "Mixer.hpp"
void Mixer_Base::noTemplateInvolved()
{
cout << "noTemplateInvolved\n";
}
Mixer_Base::Mixer_Base(int count) : mixcount(count)
{}
//Target Compiled to User.exe
//This target imports Provider.lib
#include <Provider\Mixer.hpp>
#pragma comment(lib, "Provider.lib")
struct awsome { static void log() { cout << "awsome\n"; } };
int main()
{
Mixer n(4);
n.callingTemplate();
n.noTemplateInvolved();
Mixer_tempalte<awsome> a(3);
a.callingTemplate();
a.noTemplateInvolved();
return 0;
}
In a way an annotation feels just like the base class feels. Everything in the base class is now annotated the way I wanted it to be, though this does not reduce inheritance.
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.
I have a couple functions that I want to use in many different classes. I have a couple classes that are derived from one base class and so tried to make it so that the base class held the functions and then the child classes could just call them. This seemed to cause linking errors, and so following advice from this question (Advantages of classes with only static methods in C++) I decided to give namespaces a swing, but the only file that is included by every header/file is resource.h, and I don't want to put a namespace for my functions in there as it seems to specialised to mess with.
My question is, how do I make a class that only includes a namespace, or the functions I want to use, so that I can just include this class and use the functions as desired?
Thank you in advance for the help, the answers I've found on the internet only focus on one file, not multiple files like I'm hoping to address :)
You seem confused about how namespaces are used. Here are some things to keep in mind when working with namespaces:
You create a namespace using the syntax namespace identifier { /* stuff */ }. Everything between the { } will be in this namespace.
You cannot create a namespace inside a user-defined type or function.
A namespace is an open group construct. This means you can add more stuff into this namespace later on in some other piece of code.
Namespaces aren't declared unlike some of the other language constructs.
If you want certain classes and/or functions inside a namespace scope, enclose it with the namespace syntax in the header of where it's defined. Modules using those classes will see the namespace when the headers get #include'd.
For example, in your Entity.h you might do:
// Entity.h
#pragma once
namespace EntityModule{
class Entity
{
public:
Entity();
~Entity();
// more Entity stuff
};
struct EntityFactory
{
static Entity* Create(int entity_id);
};
}
inside your main.cpp you access it like this:
#include "Entity.h"
int main()
{
EntityModule::Entity *e = EntityModule::EntityFactory::Create(42);
}
If you also want Player to be inside this namespace then just surround that with namespace EntityModule too:
// Player.h
#pragma once
#include "Entity.h"
namespace EntityModule{
class Player : public Entity
{
// stuff stuff stuff
};
}
This works because of point #3 above.
If for some reason you feel you need to create a namespace inside a class, you can simulate this to an extent using nested classes:
class Entity
{
public:
struct InnerEntity
{
static void inner_stuff();
static int more_inner_stuff;
private:
InnerEntity();
InnerEntity(const InnerEntity &);
};
// stuff stuff stuff
};
Some important differences and caveats doing it this way though:
Everything is qualified with static to indicate there's no specific instance associated.
Can be passed as a template parameter.
Requires a ; at the end.
You can't create a convenient shorthand with abusing namespace Entity::InnerEntity;. But perhaps this is a good thing.
Unlike namespaces, class and struct are closed constructs. That means you cannot extend what members it contains once defined. Doing so will cause a multiple definition error.
You can put anything in a namespace, but you can't put namespaces inside things ( that's not a very formal way of saying it but I hope you get what I mean.
Valid
namespace foospace
{
class foo
{
public :
foo();
~foo();
void eatFoo();
};
}
Invalid
namespace foospace
{
class foo
{
public :
foo();
~foo();
namespace eatspace
{
void eatFoo();
}
};
}
I'm not 100% certain that the second example wouldn't compile, but regardless, you shouldn't do it.
Now, from your comments it sounds like you want something like this :
In the file Entity.h, your entity class definition :
namespace EntitySpace
{
class Entity
{
public :
Entity();
~Entity();
};
}
In the file Player.h
#include "Entity.h"
namespace EntitySpace
{
class Player : public Entity
{
public :
Player();
~Player();
};
}
In the file main.cpp
#include "Player.h"
int main()
{
EntitySpace::Player p1;
EntitySpace::Player p2;
}
So you call upon Player in the EntitySpace namespace. Hope this answers what you were asking.
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
}