I have a class that contain two private int , one is const (m_id) and the other one is static (next_id).
I want to set m_id to next_id and increment next_id each time I create an object of the class.
But since it's a const I can't set it like that :
Class::Class()
{
m_id = next_id++;
}
I need to set it like that
Class::Class() :m_id(next_id)
{
next_id++;
}
But that's not good either because I can't access private static like that.
Someone told me that const is not intented to be used for that, so to simply remove it. Is that really the only solution?
edit : here the full header and source
header
#ifndef ENTITY_H_LEA12OED
#define ENTITY_H_LEA12OED
#include "EntityKey.h"
#include "ComponentManager.h"
class Entity
{
public:
Entity ();
virtual ~Entity ();
private:
ekey m_key;
ComponentManager m_componentManager;
const int m_id;
static int next_id;
};
#endif /* end of include guard: ENTITY_H_LEA12OED */
source
#include "Entity.h"
Entity::Entity() :m_id(next_id++)
{
}
Entity::~Entity()
{
}
(of course EntityKey and ComponentManager doesn't have anything to do with my question)
(edit 2: corrected some errors in the code due to testing)
You need to define next_id, or else it will compile, but not link. Like so:
class Class
{
/* whatever */
};
Class::Class() :m_id(next_id++)
{
/* whatever */
}
int Class::next_id = 0;
Related
This is about the following setup of an application that uses (abstract) functionality from a *.dll and a static library and which causes read access violation at last (further details are provided below the code):
... static library ...
// InterfaceWrap.h
//-----------
// dummy include
#include <SomeTClass.h>
template<typename T>
class InterfaceWrap
{
std::shared_ptr<SomeTClass<T>> m_somePtr;
public:
InterfaceWrap();
~InterfaceWrap();
void AnyAction();
};
template<typename T>
InterfaceWrap<T>::InterfaceWrap() {
m_somePtr = std::make_shared<SomeTClass<T>>();
}
template<typename T>
void InterfaceWrap<T>::AnyAction() {
m_somePtr->SomeAction();
}
... *.dll ...
// Proc.h
//-----------
// correct forward declaration?
class ThisInterface;
#include <InterfaceWrap.h>
class DLL Proc
{
std::shared_ptr<InterfaceWrap <ThisInterface>> m_interfaceWrapPtr;
public:
Proc();
~Proc();
InterfaceWrap<ThisInterface>* GetPtr();
};
// Proc.cpp
//-----------
// what about forward declaration here?
Proc::Proc() {
m_interfaceWrapPtr = std::make_shared<InterfaceWrap<ThisInterface>>();
}
InterfaceWrap<ThisInterface>* Proc::GetPtr() {
return m_interfaceWrapPtr.get();
}
... the application ...
// main.cpp
//-----------
#include <Proc.h>
// dummy includes
#include <ThisType01.h>
#include <ThisType02.h>
#include <ThisType11.h>
#include <ThisType12.h>
class ThisInterfaceA {
public:
using Type1 = ThisType01;
using Type2 = ThisType02;
};
class ThisInterfaceB { // not needed here but perhaps illustrative
public:
using Type1 = ThisType11;
using Type2 = ThisType12;
};
using ThisInterface = ThisInterfaceA;
int main(int argc, char * argv[])
{
Proc proc;
proc.GetPtr()->AnyAction();
return 0;
}
The crucial intention behind this construction is to keep the Proc and InterfaceWrap classes as abstract as possible, i.e., having them not depending directly on a chosen "interface" like ThisInterfaceA. Moreover I would like to keep the feature, that Proc is not a template class.
Obviously there are problems, of which I'm not sure how to resolve them nicely:
The line using ThisInterface = ThisInterfaceA does not work as it leads to compilation errors for the dll source codes, basically saying that ThisInterface is not known. If however, instead of this line, e.g., ThisInterfaceA is replaced by ThisInterface directly, everything compiles and links fine, at least.
Even if everything compiles and links (compare 1.), there would ultimately occur a read access violation, which concerns m_interfaceWrapPtr or m_somePtr.
What I wonder in particular is, whether properly applied forward declaration is capable of resolving the above issues and allowing to keep the feature that Proc is that abstract (or even more?) and not a template class?
Why not use real interface and DIP:
struct IAnyAction
{
virtual ~IAnyAction() = default;
virtual void AnyAction() = 0;
};
class Proc
{
std::shared_ptr<IAnyAction> m_interface;
public:
Proc(std::shared_ptr<IAnyAction> anyAction) : m_interface(anyAction) {}
IAnyAction* GetPtr() { return m_interface.get(); }
};
template<typename T>
class InterfaceWrap : public IAnyAction
{
std::shared_ptr<SomeTClass<T>> m_somePtr;
public:
InterfaceWrap();
void AnyAction() override { m_somePtr->SomeAction(); }
};
and
using ThisInterface = ThisInterfaceA; // For easy/quick way to change concrete type for interface
int main()
{
Proc proc(std::make_shared<InterfaceWrap<ThisInterface>>());
proc.GetPtr()->AnyAction();
}
In case anyone is interested, in what follows I provide the edited example code (from the beginning) as it finally works for me.
The solution is basically the answer of Jarod42 (Perhaps this overall approach may not be the most elegant one, as pointed out in the other comments. However, I guess some purposes may justify it).
However, there is one little thing added: casted void pointer arguments. To me this turns out useful when extending the original problem towards, e.g., the member AnyAction having an argument of yet unspecified but "known" type.
... static library ...
// InterfaceWrap.h
//-----------
// dummy include
#include <SomeTClass.h>
struct IAnyAction
{
virtual ~IAnyAction() = default;
virtual void AnyAction(void* arg) = 0;
};
template<typename T>
class InterfaceWrap : public IAnyAction
{
std::shared_ptr<SomeTClass<T>> m_somePtr;
public:
InterfaceWrap();
void AnyAction(void* arg);
};
template<typename T>
InterfaceWrap<T>::InterfaceWrap(){
m_somePtr = std::make_shared<SomeTClass<T>>();
}
template<typename T>
void InterfaceWrap<T>::AnyAction(void* arg) override {
auto thisArg = static_cast<T::Type1*>(arg);
m_somePtr->SomeAction(*thisArg);
}
... *.dll ...
// Proc.h
//-----------
#include <InterfaceWrap.h>
class DLL Proc
{
std::shared_ptr<IAnyAction> m_interfaceWrapPtr;
public:
Proc(std::shared_ptr<IAnyAction> interfaceWrapPtr);
~Proc();
IAnyAction* GetPtr();
};
// Proc.cpp
//-----------
Proc::Proc(std::shared_ptr<IAnyAction> interfaceWrapPtr) : m_interfaceWrapPtr(interfaceWrapPtr) {
}
IAnyAction* Proc::GetPtr() {
return m_interfaceWrapPtr.get();
}
... the application ...
// main.cpp
//-----------
#include <Proc.h>
// dummy includes
#include <ThisType01.h>
#include <ThisType02.h>
#include <ThisType11.h>
#include <ThisType12.h>
class ThisInterfaceA {
public:
using Type1 = ThisType01;
using Type2 = ThisType02;
};
class ThisInterfaceB { // not needed here but perhaps illustrative
public:
using Type1 = ThisType11;
using Type2 = ThisType12;
};
using ThisInterface = ThisInterfaceA;
int main(int argc, char * argv[])
{
Proc proc(std::make_shared<InterfaceWrap<ThisInterface>>());
auto type1 = std::make_shared<ThisInterface::Type1*>();
proc.GetPtr()->AnyAction(type1.get());
return 0;
}
Say I make a class collection
#ifndef COLLECTION_H
#define COLLECTION_H
#include <array>
class collection
{
protected:
std::array<std::shared_ptr<items>, 4> m_item;
public:
collection(std::array<std::shared_ptr<items>, 4> item)
: m_item(item)
{}
auto operator[] (size_t index) { return m_item(index); };
};
#endif //COLLECTION_H
and I create a child class items that initializes the data members inside the parent class
#include "collection.h"
#include "items.h"
class variation_1 : public collection
{
public:
variation_1() : Base( {std::make_shared<item_1>(),
std::make_shared<item_2>(),
std::make_shared<item_3>(),
std::make_shared<item_4>()}) {}
};
I used shared pointers inside the array because I have another class with its own set of functions that initialize the data members of an item class.
//items.h file
#ifndef ITEMS_H
#define ITEMS_H
#include <string>
class items
{
protected:
std::string m_ItemName;
int m_Cost;
public:
items(const std::string& name, int cost)
: m_ItemName(name), m_Cost(cost)
{}
virtual std::string getItemName() const { return this->m_ItemName; };
virtual int getItemCost() const { return this->m_Cost; };
};
#endif //ITEMS_H
#include "items.h"
class item_1 : public items
{
public:
item_1() : items("Item 1", 40)
{}
};
//and so on and so forth..
My question is, how do I access and print the different values inside the item array every time a new object of data type collection is created? Also, I'm still very new to this, so I'm not entirely sure if I am using the shared_ptr correctly. If there are better ways to go about this, I'd appreciate it if you'd point me (pun not intended) in the right direction.
The problem I am facing is somehow related to "loop inclusion" or "incompleted class"
I have 2 classes:
ControllerManager, this class is declared as Singleton, this class has a object of AuxController.
AuxController, this class has a function that needs to get the instance of ControllerManager
The problem is: when compiling source code, it fails with error "incomplete type" or "invalid type"
Is there any way to fix this problem?
or is there any other way to redesign code structure?
Source code
ControllerManager.h
#ifndef CONTROLLERMANAGER_H
#define CONTROLLERMANAGER_H
#include "auxcontroller.h"
class ControllerManager
{
/* This class is defined as Singleton class */
private:
/* 1. define a private static instance */
static ControllerManager *inst;
public:
/* 2. define a public static accessor */
static ControllerManager *getInstance(){
/* 3. do lazy initialization */
if(!inst){
inst = new ControllerManager();
}
return inst;
}
protected:
/* 4. Define all accessors to be protected */
ControllerManager();
~ControllerManager();
/* property */
private:
int m_code;
public:
int getCode()
{
return m_code;
}
void setCode(int _code)
{
m_code = _code;
}
/* below code causes fail of compilation */
public:
AuxController m_auxcontroller;
};
#endif // CONTROLLERMANAGER_H
ControllerManager.cpp
#include "controllermanager.h"
/* 5. initialize static variable */
ControllerManager *ControllerManager::inst = 0;
ControllerManager::ControllerManager()
{
m_code = 15;
}
ControllerManager::~ControllerManager()
{
delete inst;
}
AuxController.h
#ifndef AUXCONTROLLER_H
#define AUXCONTROLLER_H
/* if do NOT include controllermanager.h with below line,
* and declare ControllerManager class as a forward declaration:
*
* class ControllerManager;
*
* compiler will stop due to "incomplete type"
*/
#include "controllermanager.h"
class AuxController
{
public:
AuxController();
void setControllerCode(int code);
};
#endif // AUXCONTROLLER_H
AuxController.cpp
#include "auxcontroller.h"
AuxController::AuxController()
{
}
void AuxController::setControllerCode(int code)
{
/* if do NOT include controllermanager.h ,
* and declare ControllerManager class as a forward declaration in the header file:
*
* class ControllerManager;
*
* compiler will stop due to "incomplete type" at this line
*
*/
ControllerManager::getInstance()->setCode(code);
}
main.cpp
#include "controllermanager.h"
int main(int argc, char *argv[])
{
ControllerManager *ctlMng = ControllerManager::getInstance();
ctlMng->setCode(10);
return 0;
}
Do not include "controllermanager.h" inside auxcontroller.h, but do include it inside auxcontroller.cpp.
In general you should not include header files by other header files if it can be avoided. Use forward declaration instead. But do include all required header files from cpp files.
The problem consists into a cycle dependency.
In order to solve that problem: use forward declaration and include all needed header only in the cpp (compilation-unit) file.
In ControllerManager.hpp:
class AuxController;
class ControllerManager {
// ...
public: AuxController* m_auxcontroller;
};
// Remember to not use m_auxcontroller in the header file, JUST declaration are allowed.
Note: you have to use pointers or references to the forwarded class, so remember to initialize them correctly.
In the ControllerManager.cpp:
#include "ControllerManager.hpp"
#include "AuxController.hpp" // In Cpp file include everything you need.
// ...
The same in the class AuxController.
In the AuxController.hpp:
// You dont need header of other file in this case.
class AuxController {
// ...
};
In AuxController.cpp:
#include "AuxController.hpp"
#include "ControllerManager.hpp"
// ...
I have an issue when trying to initialize static members of a static class template.
Basically, what I thought this approach would be useful for:
I have a lot of objects, which are of course all of the same Base type but they have differing object types. I just want to manipulate these objects, that's why I decided to use a static template as there are quite a number of different types these object can consist of.
However, for logging and options passing I wanted to add the corresponding members to the template whithout having to write initializers for every derived static class.
Please note that the following code is not actually working, because there is some SDK involved.
I'm just aksing for the right approach, not right code.
Thanks in advance. :)
template.h:
#ifndef _TEMPLATE_H
#define _TEMPLATE_H
#include "stats.h"
template<class T>
class TemplateObj
{
public:
static void SetParameters(const Options& options)
{
T::_options = options; // Is this even possible?
T::Init();
T::DoStuff(_options);
}
protected:
static void Message() { stats.Print("Message from Template static method"); }
static Stats& TemplateObj<T>::stats = Stats::GetInstance(); // This will not work as this is a non-trivial initializer, how to do it correctly? Stats::GetInstance() retrieves a singleton instance
static Options& TemplateObj<T>::_options; // Possible?
};
#endif
derived.h:
#ifndef _DERIVED_H
#define _DERIVED_H
#include "template.h"
class Derived :TemplateObj < Derived >
{
public:
static void Init();
static void DoStuff(Options& options)
};
#endif
derived.cpp:
#include "derived.h"
void Derived::Init()
{
// Init stuff here
TemplateObj::Message(); // Call static method from template directly
}
void Derived::DoStuff(Options& options)
{
// Do something with options
stats.Print("Message from derived static method."); // Access to "stats" here. "stats" should be declared and initialized inside the template.
options.Load(); // Example
}
main.h
#include "derived.h"
main()
{
TemplateObj<Derived>::SetParameters(new Options);
}
Basically, you don't need to put TemplateObj<T>:: before the function definition if it is inside the class definition. The following two are both valid:
template<class T>
class A{
void func( void );
};
template<class T>
void A<T>::func() { /* Okay */ }
template<class T>
class B {
void func( void ){ /* Okay */ }
};
In your case, replace the following static Stats& TemplateObj<T>::stats = Stats::GetInstance(); with static Stats& stat() { return Stats::GetInstance(); }
And the following static Options& TemplateObj<T>::_options; with this static Options& _options;.
On the other hand, replace this T::_options = options; with TemplateObj<T>::_options = options;.
So I am trying to implement a program that has a scoreboard and two players, I am trying to make it so that the two players share a scoreboard using the singleton pattern. However when I try to use methods on the global scoreboard defined in the player classes I always get a "run failed" message.
These are my two header files, I can provide the full implementation if it's necessary.
#ifndef PLAYER_H
#define PLAYER_H
#include "scoreboard.h"
#include <string>
#include <fstream>
class Player{
private:
std::ifstream file1;
std::ifstream file2;
static Scoreboard* _game;
public:
static Scoreboard* Game();
void makeMove(const char,const std::string);
};
#endif
#ifndef SCOREBOARD_H
#define SCOREBOARD_H
class Scoreboard{
private:
int aWin;
int bWin;
int LIMIT;
int curCounter;
public:
void resetWins();
void addWin(char);
void makeMove(const int, char);
void startGame(const int, const int);
int getWin(char);
int getTotal();
int getLimit();
};
#endif /* SCOREBOARD_H */
in player.cc
Scoreboard* Player::_game = 0;
Scoreboard* Player::Game(){
if (_game = 0)
{
_game = new Scoreboard;
_game->resetWins();
}
return _game;
}
Along with the makeMove method
Your Scoreboard instance does not need to be a pointer:
static Scoreboard _game;
// ...
static Scoreboard& Game() { return _game; }
Or alternatively, just leave out the class declaration of _game:
// you can either make this function static or non-static
Scoreboard& Game()
{
static Scoreboard game; // but this variable MUST be static
return game;
}
That will do the same thing without the memory management issues.
This will create a single instance of Scoreboard for all Players. If you only ever wanted to have a single instance of Scoreboard (e.g. if you had a Referees class that needed to see the scoreboard as well), you would modify your scoreboard class:
class Scoreboard
{
private:
// all your data members
Scoreboard() {} // your default constructor - note that it is private!
public:
// other methods
Scoreboard& getInstance()
{
static Scoreboard instance;
return instance;
}
};
Then, to access it in your other classes, you would include the scoreboard header and use it as:
#include "Scoreboard.h"
void my_func()
{
Scoreboard& scoreboard = Scoreboard::getInstance();
scoreboard.DoSomething();
}
In Player::Game, you have written
if (_game = 0)
that is setting _game = 0 and evaluating to false, so that you don't actually create the scoreboard. Change it for:
if (_game == 0)