Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm making an IRC bot in C++, and it's supposed to react to messages in the IRC channel. The IRC channel belongs to a multiplayer game server, where people can communicate from in-game to IRC and vice versa. (Basically you can see things happening on the server, including chat, without actually having to be in the game).
I have a pretty basic class hierarchy set up to represent gradually more specific types of IRC events.
Represented on a graph it looks like this
Now, I'm trying to implement this kind of multi-level inheritance in C++, like this (please excuse my inconsistent styling. I also omitted CIrcCommand because it's very similar to CIngameCommand, and has the same problem)
CIrcEvent
class CIrcEvent
{
protected:
EventType m_type;
private:
void(*HandlerFunc)(std::string& nick, std::string& chan, std::vector<std::string>& message);
public:
CIrcEvent(void(*handler_ptr)(std::string& nick, std::string& chan, std::vector<std::string>& message))
{
m_type = EventType::IRCEVENT;
HandlerFunc = handler_ptr;
}
};
CCommand
class CCommand : public CIrcEvent
{
protected:
std::string m_name;
int m_level;
public:
std::string& GetCommandName() { return this->m_name; }
int GetLevel() { return this->m_level; }
};
CIngameCommand
class CIngameCommand : public CCommand
{
public:
CIngameCommand(std::string& CmdName, int CmdLevel, void(*CmdFuncPointer)(std::string& nick, std::vector<std::string>& message))
{
m_type = EventType::IGCMD;
m_name = CmdName;
m_level = CmdLevel;
HandlerFunc = CmdFuncPointer;
}
void Call(std::string& nick, std::vector<std::string>& message) { HandlerFunc(nick, message); }
private:
void(*HandlerFunc)(std::string& nick, std::vector<std::string>& message);
};
But inside of class CIngameCommand's constructor's definition...
CIngameCommand(std::string& CmdName, int CmdLevel, void(*CmdFuncPointer)(std::string& nick, std::vector<std::string>& message))
{ // <-- error on this line
m_type = EventType::IGCMD;
... I get a C2280 error.
IRCCommand.h(63): error C2280: 'CCommand::CCommand(void)': attempting to reference a deleted function
IRCCommand.h(43): note: compiler has generated 'CCommand::CCommand' here
I'm not sure what I'm doing wrong. I am aware that I haven't defined a custom constructor for CCommand class, but that's because as opposed to all the others, I'm only planning to use CCommand's derived classes (CIngameCommand and CIrcCommand), I'm never going to use it on its own.
What can I do to circumvent this error? Is my design flawed? If so, how can I implement this differently?
The deleted function is the default constructor of CIrcEvent. It has a user defined constructor and then that constructor has to be called from the derived class.
You don't define any constructors in CCommand so "compiler has generated 'CCommand::CCommand'". Such a compiler generated constructor will also call the base class' default constructor - but the base class doesn't have one!
Related
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++ novice here.
I'm trying to teach myself C++ by working on a project to create a Robot that gets commands from and sends telemetry back to a remote server.
I have a TcpCom class on the Robot which contains the socket connection and public functions to send messages and receive messages from the server:
#ifndef TCPCOM_H
#define TCPCOM_H
#define BOOST_DATE_TIME_NO_LIB
#include <boost/asio.hpp>
#include <boost/interprocess/sync/interprocess_semaphore.hpp>
#include <deque>
#include <mutex>
#include "COM.h"
class TcpCom : public COM
{
public:
TcpCom() : io_srv(), tcpSocket(io_srv), remoteHost(""), remotePort(""), connectedToRemoteHost(false), outboundMsgQueue(), outboundMsgQueueMutex(),
messagesInOutboundMsgQueue(0), incomingMsgQueue(), incomingMsgQueueMutex()
{}
int initialize();
void connectToRemoteHost(const std::string host, const std::string port);
void disconnectFromRemoteHost();
bool messagesWaitingInIncomingMsgQueue();
SoftwareBusMsg getMsgFromIncomingMsgQueue();
void addMsgToOutboundMsgQueue(SoftwareBusMsg& sbMsg);
bool isConnected();
private:
void writeOutboundMsgToSocket();
void deserializeHeader(std::string headerStr, MsgHeader& msgHdr);
void addMessageToIncomingMsgQueue(SoftwareBusMsg& sbMsg);
void readIncomingMsgHeader(MsgHeader& msgHdr);
std::string readIncomingMsgData(uint32_t msgDataLength);
SoftwareBusMsg readMsgFromSocket();
void incomingMsgThread();
void outboundMsgThread();
void startReadAndWriteThreads();
boost::asio::io_service io_srv;
boost::asio::ip::tcp::socket tcpSocket;
std::string remoteHost;
std::string remotePort;
bool connectedToRemoteHost;
std::deque<std::string> outboundMsgQueue;
std::mutex outboundMsgQueueMutex;
boost::interprocess::interprocess_semaphore messagesInOutboundMsgQueue;
std::deque<SoftwareBusMsg> incomingMsgQueue;
std::mutex incomingMsgQueueMutex;
//boost::interprocess::interprocess_semaphore messagesInIncomingMsgQueue;
};
#endif
I want the other classes, such as those responsible for motor control, to have the capability to send messages to the server for telemetry/error reporting. I may be wrong here, but it seems like it would be poor design to directly pass an instance of the TcpCom class to each class that needs the ability to send messages to the server.
Instead, I tried creating a EventReporter class that has a private member that is a reference to the TcpComclass. This would allow the encapsulation of code for handling different types of events (info, errors) and I could pass an initialized 'EventReporter' object to everything that needs it.
#include "TcpCom.hpp"
class EventReporter
{
public:
EventReporter(TcpCom& tcpComIn) : tcpCom(tcpComIn)
{}
//Will contain call to tcpCom.addMsgToOutboundMsgQueue()
void reportEvent(std::string eventType, std::string message);
private:
TcpCom tcpCom;
};
When I tried compiling this code I got a few errors:
error: use of deleted function 'TcpCom::TcpCom(const TcpCom&)'
error: use of deleted function 'boost::asio::io_service(const boost::asio::io_service&)'
It looks like my new class would be trying to make a copy of TcpCom, which I thought I was avoiding by passing it by reference.
Should I use something like a unique_ptr to avoid copying TcpCom, or is there a better way to make networking functions accessible from other classes?
Thanks!
Kind of tossed up whether to answer this or close as a typo, so I'll post and let the question's Asker tell me.
In
class EventReporter
{
public:
EventReporter(TcpCom& tcpComIn) : tcpCom(tcpComIn)
{}
//Will contain call to tcpCom.addMsgToOutboundMsgQueue()
void reportEvent(std::string eventType, std::string message);
private:
TcpCom tcpCom; //<- this is not a reference
};
TcpCom tcpCom; defines an instance of TcpCom, not a reference to a TcpCom as the Asker stated they wanted, so tcpCom(tcpComIn) in the member initializer list (Good on them for using the list, by the way. Many C++ programmers who think they are no longer learning don't seem to know they exist) performs the copy They are trying to avoid by passing by reference in the parameter list.
The error messages result from members (std::mutex at the very least. Multiple copies of a mutex would be bad) of TcpCom being uncopyable, so you can't copy one even if you want to.
The simple solution is
class EventReporter
{
public:
EventReporter(TcpCom& tcpComIn) : tcpCom(tcpComIn)
{}
//Will contain call to tcpCom.addMsgToOutboundMsgQueue()
void reportEvent(std::string eventType, std::string message);
private:
TcpCom & tcpCom; //<- change made here
};
Unless the Asker has other uncopyable objects also being copied else where in their code or the the EventReporter instance can outlive the source TcpCom they should be good to go.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have a struct defined in a header file. Then I have a singleton class where I am trying to use the struct. When I call ResetVars() from another class I get an access violation when it hits the line that says test.numResponses = "TEST". I am assuming this has something to do with initialization but I haven't been able to solve it. I am new to c++ and I have no idea how to get around this. Thanks for any help.
struct.h
typedef struct POLL_DATA
{
std::string numResponses;
std::string type;
std::string question;
} POLL_DATA;
ControlPolls.h
class ControlPolls
{
private:
static bool instanceFlag;
static ControlExitPolls *controlSingle;
ControlExitPolls();
POLL_DATA test;
public:
static ControlExitPolls* getInstance();
void ResetVars();
};
ControlPolls.cpp
#include "ControlPolls.h"
bool ControlPolls::instanceFlag = false;
ControlPolls* ControlPolls::controlSingle = NULL;
//Private Constructor
ControlExitPolls::ControlExitPolls()
{
};
//Get instance
ControlPolls* ControlPolls::getInstance()
{
if(!instanceFlag)
{
controlSingle = &ControlPolls();
instanceFlag = true;
return controlSingle;
}
else
{
return controlSingle;
}
}
void ControlExitPolls::ResetVars()
{
test.numResponses = "TEST";
}
callingClass.cpp
ControlPolls *controlSingleton;
controlSingleton = ControlPolls::getInstance();
controlSingleton->getInstance()->ResetVars();
You've been struck by C++'s Most Vexing Parse, a compiler rule that says anything that could be a function declaration is a function declaration. The culprit is this line:
POLL_DATA testPoll();
testPoll is treated as the declaration of a function with return type POLL_DATA. Try removing the brackets, or writing simply POLL_DATA testPoll; which implicitly calls the compiler-generated default constructor.
Another larger problem is that testPoll is a member of A, but you've hidden it and declared a local variable in your constructor, A::A(). I suggest you remove the constructor altogether because the implicit constructor will suffice.
Some more notes on your code:
You've declared your class a but refer to it later as A.
You've written an implementation of a constructor for A without declaring it like a proper forward declaration.
Also, typedef struct is not needed in C++. It is sufficient and encouraged to write:
struct POLLDATA {
...
};
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I'm a beginner to C++ and I was wondering if there was a good way to access a member of another object.
Currently I'm using this to access the members:
&_HeatSensor->IsOverheating == true;
&_LeftLegSensor->IsStalled == true;
/*... many more similar ones but different names*/
Where HeatSensor or LeftLegSensor is the name of the object and IsOverheating or IsStalled is a Boolean member in the object.
I want to create a new SensorOverLimit class, and create many objects(ex: Left Leg, MotorTemperature... etc.
To save time and reuse code, I want to be able to pass something that can reference the Boolean members that were created in the constructor and then save the location via reference or pointer as a member in the new SensorOverLimit object.
SensorOverLimit.cpp
SensorOverLimit::SensorOverLimit(bool* SensorAddress)
{
bool* Sensor = SensorAddress;
}
SensorOverLimit::Check()
{
if (SensorAddress == true)
{
somefunction();
}
}
main.cpp:
SensorOverLimit Overheating = new SensorOverLimit(bool* &_HeatSensor->IsOverheating);
SensorOverLimit DamagedLeg = new SensorOverLimit(bool* &_LeftLegSensor->IsStalled);
This doesn't work, does anyone have any ideas for how to get this to work?
Edit: Changed question, new answer...
SensorOverLimit.h:
class SensorOverLimit
{
bool* sensor;
public:
SensorOverLimit(bool* sensorAddress);
void check();
};
SensorOverLimit.cpp:
SensorOverLimit::SensorOverLimit(bool* sensorAddress)
: sensor(sensorAddress)
{
}
void SensorOverLimit::check()
{
if(*sensor)
{
somefunction();
}
}
Have a look at Remy's answer for references instead of pointers (bool& instead of bool*, and you can omit dereferencing (if(sensor))
main.cpp:
HeatSensor heatSensor;
LeftLegSensor leftLegSensor;
SensorOverLimit overHeating(&heatSensor.isOverheating);
SensorOverLimit leftLegDamaged(&leftLegSensor.isStalled);
int main(int, char*[])
{
// ...
return 0;
}
You might have noticed: I directly instantiated global variables. This is often more appropriate in embedded environments, at least easier to use.
Be careful with identifiers starting with an underscore - these are reserved in many cases (C++ standard, 2.10):
Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
Each identifier that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Edit 2:
I'm coming up with a completely different design, inverting what you had so far:
class Sensor
{
public:
Sensor()
: isActive(false)
{ }
virtual ~Sensor()
{ }
void check()
{
if(getValue() != isActive)
{
isActive = !isActive;
if(isActive)
{
someFunction();
}
}
}
private:
bool isActive;
virtual bool getValue() = 0;
};
class HeatSensor : public Sensor
{
virtual bool getValue()
{
bool isActive = false;
// do what ever is necessary to detect overheat
// e. g. read from ADC and compare against threshold
return isActive;
}
};
class LegSensor : public Sensor
{
bool isSignal;
virtual bool getValue()
{
// do what ever is necessary to detect stalled leg
// e. g.: simply returning the value that has been set from
// within an interrupt handler
return isSignal;
}
};
Not really happy about the names of my members, you might find something better...
What is your intention of this design, however? Are you going to iterate over each city, checking the bool pointers? Seems a questionable design to me...
I suggest an alternative for you:
Each Sensor gets a SensorOverLimit* pointer, you might call it 'controller' or whatever seems appropriate to you. Then add functions to each Sensor class: oveheating(), stalling(), etc. Within these functions, you call a newly defined function of SensorOverLimit: disturb(int reason, Sensor* source). Instead of int, you could define an enum containing all possible reasons, such as Overheat, Stall, etc.
Could look like this:
class Sensor;
class SensorOverLimit
{
// appropriate members
public:
enum Disturbance
{
Overheat,
Stall,
};
SensorOverLimit() {}
void disturb(Disturbance reason, Sensor* source)
{
someFunction();
}
};
class Sensor
{
protected:
SensorOverLimit* controller;
public:
// ctor, getters, setters as needed
Sensor(SensorOverLimit* aController) : controller(aController) {}
};
class HeatSensor : public Sensor
{
public:
// ctor, getters, setters as needed
HeatSensor(SensorOverLimit* aController) : Sensor(aController) {}
void overheating()
{
if (controller)
controller->disturb(SensorOverLimit::Overheat, this);
}
};
class LegSensor : public Sensor
{
public:
// ctor, getters, setters as needed
LegSensor(SensorOverLimit* aController) : Sensor(aController) {}
void stalling()
{
if (controller)
controller->disturb(SensorOverLimit::Stall, this);
}
};
SensorOverLimit controller;
HeatSensor heatSensor(&controller);
LegSensor leftLegSensor(&controller);
int main(int, char*[])
{
// ...
heatSensor.overheating();
//...
leftLegSensor.stalling();
//...
return 0;
}
Advantage: You can associate many sensors to one and the same controller.
You can use a bool* pointer like this:
class SensorOverLimit
{
public:
bool* Sensor;
SensorOverLimit(bool* SensorAddress);
void Check();
};
...
SensorOverLimit::SensorOverLimit(bool* SensorAddress)
: Sensor(SensorAddress)
{
Check();
}
void SensorOverLimit::Check()
{
if (*Sensor)
{
somefunction();
}
}
SensorOverLimit *Overheating = new SensorOverLimit(&(_HeatSensor->IsOverheating));
SensorOverLimit *DamagedLeg = new SensorOverLimit(&(_LeftLegSensor->IsStalled));
...
Then you can do this:
_HeatSensor->IsOverheating = true;
...
Overheating->Check();
_LeftLegSensor->IsStalled = true;
...
DamagedLeg->Check();
With that said, it would be safer to use references instead of pointers:
class SensorOverLimit
{
public:
bool& Sensor;
SensorOverLimit(bool& SensorAddress);
void Check();
};
...
SensorOverLimit::SensorOverLimit(bool& SensorAddress)
: Sensor(SensorAddress)
{
Check();
}
void SensorOverLimit::Check()
{
if (Sensor)
{
somefunction();
}
}
SensorOverLimit *Overheating = new SensorOverLimit(_HeatSensor->IsOverheating);
SensorOverLimit *DamagedLeg = new SensorOverLimit(_LeftLegSensor->IsStalled);
...
_HeatSensor->IsOverheating = true;
...
Overheating->Check();
_LeftLegSensor->IsStalled = true;
...
DamagedLeg->Check();
Is there a particular reason why you're not using getters and setters in order to access the members of your objects?
If you're referencing to all your objects as pointers, you may want to reconsider that practice. This StackOverflow question gives some insight into common practice with C++ and pointers: Why should I use a pointer rather than the object itself?
I think the best answer to your question would actually be to familiarize yourself with the concept of pointers. This question as well the one I mentioned earlier give a good starting point - C++ Objects: When should I use pointer or reference. I think one of the best things to note is that if you are coming from a Java background, pointers and references are hidden in the code for you. Every object is a pointer and vice versa in Java. In C++, they are separate.
I think your desire to reuse code is commendable, but in this case, using pointers will probably cause unknown errors!
I'd recommend changing your constructor in the City class to actually work with the objects, not just their members (for instance, create a City with a person as your parameter, not whether the person is alive or dead). With a little more practice in object-oriented programming, you may find that it is much easier than your initial approach!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I got a problem regarding Eclipse when creating abstract classes. I'm not very used to dealing with header files and such, my code basically looks as follows: (not displaying everything, just the basic class to give an idea of how it looks)
Equipment.h
namespace Equipments {
class Equipment{
public:
virtual ~Equipment();
virtual std::string get_category() const = 0;
protected:
Equipment(std::string name);
private:
const std::string name_;
};
class Weapon : public Equipment {
public:
Weapon(std::string name, std::string something_else);
virtual ~Weapon();
std::string get_category() const override { return "Weapon"; };
private:
const std::string something_else_;
};
} //end of namespace
Now, I got a problem with both the .h and .cpp file
in the .h file, under the weapon constructor, I'm used to writing (since I don't use header files):
Weapon(std::string name, std::string something_else)
: Equipment{name}, something_else_{something_else}
{}
Since I can't do this really (to my knowledge), how do I send parameters to my parent class? (in this case, letting eclipse know that I want my name parameter sent to Equipment parent class)
Should I do it in the .cpp file and if so, how?
And now the second problem.
In the .cpp file I create my equipment class like this:
namespace Equipments {
Equipment::Equipment(std::string name) {
name_ = name;
}
Equipment::~Equipment() {
}
std::string Equipment::get_name()
{
return name_;
}
//etc
But I can't seem to create my Weapon class. If I try:
Equipment::Weapon(std::string name, std::string something_else)
I just get member decleration not found, and if I try:
Weapon::Weapon(std::string name, std::string something_else)
I get no matching function for call to 'Equipments::Equipment::Equipment()'
I'm just stuck with not knowing how eclipse want me to write my code, I know it's a bit of a noob problem but I haven't been using either header files or c++ in eclipse for quite a long time. I'm really close to just pick my laptop and program in ubuntu and gedit instead so I don't have to deal with the header classes, however, then I won't learn anything either.
But I can't seem to create my Weapon class. If I try:
Equipment::Weapon(std::string name, std::string something_else)
I just get member declaration not found,
Well, yes: your Weapon class is called Weapon, and it's constructor is called Weapon::Weapon. It inherits from Equipment, it isn't stored inside it.
and if I try:
Weapon::Weapon(std::string name, std::string something_else)
I get
no matching function for call to 'Equipments::Equipment::Equipment()'
That just means you left out the base class constructor (so it's trying to use the default constructor, which doesn't exist) - you don't show the whole code, but it ought to be
Weapon::Weapon(std::string name, std::string something_else)
: Equipment(name)
, something_else_(something_else)
{
}