Atomic member variable - c++

We are supposed to declare the private member variable trackerCoordinates as an atomic.
The .h was originally written like:
class Missile : public Attack, public Sea::Coordinates {
private:
bool hit = false;
Sea::FCoordinates trackerCoordinates;
I've tried to use the std::atomic like this:
class Missile : public Attack, public Sea::Coordinates {
private:
bool hit = false;
std::atomic<Sea::FCoordinates> trackerCoordinates;
Now, in the accompanying .cpp, in line 3, there's a new error, which gets resolved by undoing the std::atomic declaration.
Missile::Missile(Coordinates const & coordinates)
: Coordinates(coordinates),
trackerCoordinates(-1.f,-1.f) -- this line
{
}
The error says:
No matching constructor for initialization of 'std::atomicSea::FCoordinates' (aka 'atomic<TCoordinates>')
I do not know why that error happens and how to resolve it.
A bit more information: FCoordinates is a typedef of TCoordinates, which is supposed
to create coordinates given as a parameter like (x,y), and the TCoordinates constructor is noexcept declared.
Thanks in Advance for any help.

Related

Initializing a new nested class from outer class function

I'm currently learning nested classes in C++ while building a project and I currently inside setupBLE() I need to pass one of the nested classes but to init that new class I need to pass to its constructor the outer class so it can access its variables and functions but I'm not exactly sure how to pass to the constructor the pointer of the class that's trying to create it.
It's a bit confusing so I hope the code helps with it.
Like in python we have self but in C++ as far as I know we don't have that so I was wondering what should I pass to the constructor.
Code (PillDispenser.h):
class PillDispenser {
public:
explicit PillDispenser(BLEAddress deviceAddress);
private:
BLEAddress _device_address;
BLEAdvertisedDevice _device;
bool _connected;
// Device properties
std::string _device_name;
// Callbacks
static void notifyCallBack();
class AdvertisedDeviceCallBack : public BLEAdvertisedDeviceCallbacks {
PillDispenser &_outer;
explicit AdvertisedDeviceCallBack(PillDispenser &outer) : _outer(outer){};
void onResult(BLEAdvertisedDevice advertisedDevice) override;
};
}
Code (PillDispenser.cpp):
void PillDispenser::setupBLE() {
BLEScan *scanner = BLEDevice::getScan();
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack());
scanner->setInterval(SCAN_INTERVAL);
scanner->setWindow(SCAN_WINDOW);
scanner->setActiveScan(true);
scanner->start(SCAN_DURATION);
}
Issue:
This line is trying to use the default constructor which does not exist
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack());
instead you should use the explicit constructor you defined
scanner->setAdvertisedDeviceCallbacks(new AdvertisedDeviceCallBack(*this));
note that this (in this context) has type PillDispenser* so you have to dereference with * to get a PillDispenser&

no matching function for call to 'WidgetBridge::WidgetBridge()'

I've visited this forum many many many times, but this is my actual first post here. Usually I can find my answer here and I guess I've probably found it this time, but this time my knowledge is lacking to understand the solutions given (been learning C++ for the last 2 weeks).
The error I get:
no matching function for call to 'WidgetBridge::WidgetBridge()'
an extraction of my (rather lengthy) code:
class Room {
private:
//initializer list of internal objects
WidgetBridge bridge_thermostat;
WidgetBridge bridge_relay;
public:
//Constructor of the class:
Room() : bridge_thermostat(V100), bridge_relay(V107){}
void initBridges(String authThermostat, String authRelay){
bridge_thermostat.setAuthToken(authThermostat);
bridge_relay.setAuthToken(authRelay);
}
void receiveCurrentT(float param){
currentT = param;
Blynk.virtualWrite(V10, currentT);
timer.restartTimer(thermostatTimer ); //reset isDead timer for thermostat
Blynk.setProperty(V17, "color", BLYNK_GREEN); //change LED color
Blynk.virtualWrite(V17, 200);
}
} livingRoom;
BLYNK_CONNECTED() {
Blynk.syncAll();
livingRoom.initBridges("xxx", "xxxx"); //auth of: thermostat, relay
}
BLYNK_WRITE(V10){ livingRoom.receiveCurrentT(param.asFloat()); } //receive currentT from thermostat
Based on the answers I've found on this forum it appears that WidgetBridge doens't have its own constructor when called. Based on the answers given I've also tried:
public:
//Constructor of the class:
Room() : {
bridge_thermostat = V100;
bridge_relay = V107;
}
but that rendered the same error. I've continued reading about static fields, constructors, namespaces, etc. but bottomline: I'm stuck and I don't know how to fix this.
Additional info: code is for an esp8266 arduino wifi module which communicates with other esp8266's (relay and thermostat). The communication takes place through 'bridges' which are created using code from the Blynk app.
Thank you for your time!
UPDATE: I've finally found the actual calss widgetbridge itself. And from the mentioned solution I gathered that it has no constructor of itself, but it does..so now I'm really lost. Here's part of the widget class:
class WidgetBridge
: private BlynkWidgetBase
{
public:
WidgetBridge(uint8_t vPin)
: BlynkWidgetBase(vPin)
{}
void setAuthToken(const char* token) {
char mem[BLYNK_MAX_SENDBYTES];
BlynkParam cmd(mem, 0, sizeof(mem));
cmd.add(mPin);
cmd.add("i");
cmd.add(token);
Blynk.sendCmd(BLYNK_CMD_BRIDGE, 0, cmd.getBuffer(), cmd.getLength()-1);
}
(....)
};
From the code extract you posted (partial) and the error message(partial too...) , the only reasonable answer is that the WidgetBridge class as no default constructor (i.e. constructor with 0 argument).
Probably because the base class BlynkWidgetBase has no default constructor as well.
So you get compiler errors on those lines
//initializer list of internal objects
WidgetBridge bridge_thermostat;
WidgetBridge bridge_relay;
You can either implement a WidgetBride default constructor or instanciate those two variables with the constructor taking a uint8_t parameter :
//initializer list of internal objects
WidgetBridge bridge_thermostat(3);
WidgetBridge bridge_relay(4);
3 and 4 to be replaced by whatever value that makes sense, but only you can know that from the code extract

C++ class namespace weirdness

I have a C++ class using Core Audio structs on OS X.
My initial implementation was like this:
class MyClass
{
private:
AUNode _converterNode;
AURenderCallbackStruct _renderCBStruct;
public:
MyClass();
~MyClass();
inline AUNode* getConverterNode() { return &_converterNode; }
inline AURenderCallbackStruct* AURenderCallbackStruct() { return &_renderCBStruct; }
};
After reading the Poco style guides, I wanted to change the order of the private/public blocks. It then looked like this:
class MyClass
{
public:
MyClass();
~MyClass();
inline AUNode* getConverterNode() { return &_converterNode; }
inline AURenderCallbackStruct* AURenderCallbackStruct() { return &_renderCBStruct; }
private:
AUNode _converterNode;
AURenderCallbackStruct _renderCBStruct;
};
The compiler now tells me that the type AURenderCallbackStruct is unknown and tells me to replace the type name with ::AURenderCallbackStruct. When I do that, there are no compiler errors.
Weirdly, this only appears for the `AURenderCallbackStruct and not the AUNode.
The AURenderCallbackStruct is defined like this:
typedef struct AURenderCallbackStruct {
AURenderCallback inputProc;
void * inputProcRefCon;
} AURenderCallbackStruct;
and AUNode is defined like this:
typedef SInt32 AUNode;
Can anyone explain why the change of order of private/public block produces a compiler error and why the error disappears when adding a ::in front of the type?
First of all it is not clear why you named the member function as AURenderCallbackStruct that coincides with the corresponding structure's name and looks like the structure constructor.
The problem is this stupid name.
in the first case the compiler thinks that you indeed define the member function that hides the corresponding name of the structure.
In the second case the compiler thinks that you trying to call the constructor of the structure.
Simply rename the function that there would not be an ambiguity.

c++ class circular reference?

I am working on a little game engine but I got stuck at something. Explanation : I have two classes, cEntity And ObjectFactory :
cEntity
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
ObjectFactory
#include "cEntity.h"
#include <vector>
class ObjectFactory
{
static std::vector<cEntity> *entityList;
static int i, j;
public:
static void addEntity(cEntity entity) {
entityList->push_back(entity);
}
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity> *ObjectFactory::entityList = new std::vector<cEntity>();
Now I am adding new cEnity to ObjectFactory in cEntity constructor but facing an error related to circular references: for using ObjectFactor::addEntity() I need to define the ObjectFactory.h in cEntity class but it creates a circular reference.
I think your code might have an underlying architectural issue given how you have described the problem.
Your ObjectFactory should be handling the cEntities, which in turn should be unaware of the "level above". From the description of the problem you are having, it implies that you're not sure what class is in charge of what job.
Your cEntitys should expose an interface (i.e. all the stuff marked "public" in a class) that other bits of code interact with. Your ObjectFactory (which is a bit badly named if doing this job, but whatever) should in turn use that interface. The cEntitys shouldn't care who is using the interface: they have one job to do, and they do it. The ObjectFactory should have one job to do that requires it to keep a list of cEntitys around. You don't edit std::string when you use it elsewhere: why is your class any different?
That being said, there's two parts to resolving circular dependencies (beyond "Don't create code that has circular dependencies in the first place" - see the first part to this answer. That's the best way to avoid this sort of problem in my opinion)
1) Include guards. Do something like this to each header (.h) file:
#ifndef CENTITY_H
#define CENTITY_H
class cEntity:public cEntityProperty
{
Vector2 position;
Vector2 scale;
public:
cEntity(void);
cEntity(const cEntity&);
~cEntity(void);
public:
void init();
void render();
void update();
void release();
};
#endif
What this does:
The first time your file is included, CENTITY_H is not defined. The ifndef macro is thus true, and moves to the next line (defining CENTITY_H), before it moves onto the rest of your header.
The second time (and all future times), CENTITY_H is defined, so the ifndef macro skips straight to the endif, skipping your header. Subsequently, your header code only ever ends up in your compiled program once. If you want more details, try looking up how the Linker process.
2) Forward-declaration of your classes.
If ClassA needs a member of type ClassB, and ClassB needs a member of type ClassA you have a problem: neither class knows how much memory it needs to be allocated because it's dependant on another class containing itself.
The solution is that you have a pointer to the other class. Pointers are a fixed and known size by the compiler, so we don't have a problem. We do, however, need to tell the compiler to not worry too much if it runs into a symbol (class name) that we haven't previously defined yet, so we just add class Whatever; before we start using it.
In your case, change cEntity instances to pointers, and forward-declare the class at the start. You are now able to freely use ObjectFactory in cEntity.
#include "cEntity.h"
#include <vector>
class cEntity; // Compiler knows that we'll totally define this later, if we haven't already
class ObjectFactory
{
static std::vector<cEntity*> *entityList; // vector of pointers
static int i, j;
public:
static void addEntity(cEntity* entity) {
entityList->push_back(entity);
}
// Equally valid would be:
// static void addEntity(cEntity entity) {
// entityList->push_back(&entity);}
// (in both cases, you're pushing an address onto the vector.)
// Function arguments don't matter when the class is trying to work out how big it is in memory
private:
ObjectFactory(void);
~ObjectFactory(void);
};
std::vector<cEntity*> *ObjectFactory::entityList = new std::vector<cEntity*>();

I'm messing up my inheritance

So I've got a Piece class supposed to represent pieces on a board, from which I plan to have two other classes inheriting. I've gotten a lot of problems in doing so, however; here is the relevant code so far.
///
/// PIECE CLASS HERE
/// this is an abstract class from which Barrier and Pawn inherit.
class Piece
{
public:
Piece(Space* start);
sf::Shape m_Circle;
protected:
int m_X;
int m_Y;
int m_radius;
Space* CurrentSpace;
};
Piece::Piece(Space* start):
m_X(start->GetX()),
m_Y(start->GetY()),
m_radius(14),
CurrentSpace(start)
{}
///
/// BARRIER CLASS HERE
/// these are the white stones that block a player's path
class Barrier : public Piece
{
public:
Barrier(Space* initial);
void Move(Space* target, bool isCapturing);
};
Barrier::Barrier(Space* initial)
{
Piece(initial);
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
void Barrier::Move(Space* target, bool isCapturing)
{
int xChange = abs(target->GetX() - m_X);
int yChange = abs(target->GetY() - m_Y);
m_Circle.Move((float)xChange, (float)yChange);
CurrentSpace.ToggleOccupied();
if(!isCapturing)
{
(*target).ToggleOccupied();
}
CurrentSpace = target;
}
I'm getting loads of errors I don't understand, in particular:
no matching function for call to Piece::Piece()
declaration of 'Piece initial' shadows a parameter
no matching function for call to 'Barrier::Move(Piece&)'
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|
Being new to C++, I don't understand what's going wrong with any of this. I tried to build my code analogous to the code I found in the book I used to learn C++, but apparently I've overlooked some subtlety. All the functions that I try to call seem to exist in the appropriate places, and I define them with the same values as in their prototype, I think.
The first error is caused by this:
Barrier::Barrier(Space* initial)
{
Piece(initial);
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
Needs to look like:
Barrier::Barrier(Space* initial) : Piece(initial)
{
m_Circle = sf::Shape::Circle((float)m_X, (float)m_Y, (float)m_radius, sf::Color(255, 255, 255));
Move(initial);
}
The base class' constructor runs before your constructor (no matter what) -- you need to pass arguments to it if it requires arguments in the initialization list.
I'm not sure about the other errors because I don't know which lines they're occurring on.
The parenthesis in the line
Piece(initial);
are ignored by the compiler. You are declaring a variable with the same name as the parameter:
Piece initial;
To initialize the Piece base object with initial, you have to use the member initializer list:
Barrier::Barrier(Space* initial) : Piece(initial)
Also, the Move function expects two arguments, but you're only passing one. You forgot the boolean.
Good answers, all. Plus that final daunting line
request for member 'ToggleOccupied' in '((Barrier*)this)->Barrier::<anonymous>.Piece::CurrentSpace', which is of non-class type 'Space*'|
is being caused from
CurrentSpace.ToggleOccupied();
you have declared CurrentSpace to be a pointer, so this should be
CurrentSpace->ToggleOccupied();
If you want to initialize the super class, you should do it like this:
Barrier(Space* initial):
Piece(initial) {
...
}
If you don't explicitly initialize the base type, the compiler will try to initialize it by calling a constructor with an empty argument list, like this:
Barrier(Space* initial):
Piece() {
...
}
But since you don't define a constructor for Piece that takes zero arguments, you get the compiler error you described.