Constructor of virtual genetic class [duplicate] - c++

This question already has answers here:
error: use of deleted function
(6 answers)
Why can templates only be implemented in the header file?
(17 answers)
Closed 3 months ago.
I have this code:
sensor.h:
template<class T>
class Sensor {
public:
uint8_t address;
T data;
virtual void collectData() = 0;
Sensor(uint8_t address);
};
class TemperatureSensor: public Sensor<float> {
void collectData();
};
sensor.cpp:
template<typename T>
Sensor<T>::Sensor(uint8_t address) {
this->address = address;
}
void TemperatureSensor::collectData() {
//some code for collecitng data
}
main function:
TemperatureSensor sensor;
Serial.printf("%d", sensor.address);
Error:
src\sensor.cpp: In function 'void test()':
src\sensor.cpp:11:23: error: use of deleted function 'TemperatureSensor::TemperatureSensor()'
11 | TemperatureSensor sensor;
| ^~~~~~
In file included from src\sensor.cpp:1:
src/sensor.h:14:7: note: 'TemperatureSensor::TemperatureSensor()' is implicitly deleted because the default definition would be ill-formed:
14 | class TemperatureSensor: public Sensor<float> {
| ^~~~~~~~~~~~~~~~~
src/sensor.h:14:7: error: no matching function for call to 'Sensor<float>::Sensor()'
src/sensor.h:11:9: note: candidate: 'Sensor<T>::Sensor(uint8_t) [with T = float; uint8_t = unsigned char]'
11 | Sensor(uint8_t address);
| ^~~~~~
src/sensor.h:11:9: note: candidate expects 1 argument, 0 provided
src/sensor.h:6:7: note: candidate: 'constexpr Sensor<float>::Sensor(const Sensor<float>&)'
6 | class Sensor {
| ^~~~~~
src/sensor.h:6:7: note: candidate expects 1 argument, 0 provided
src/sensor.h:6:7: note: candidate: 'constexpr Sensor<float>::Sensor(Sensor<float>&&)'
src/sensor.h:6:7: note: candidate expects 1 argument, 0 provided
*** [.pio\build\nodemcuv2\src\sensor.cpp.o] Error 1
I want to have multiplte options of same base class(Sensor class) and extend it(I think this is rigth name). I cant create new instance of TemperatureSensor, from error i asume that i need to pass reference of Sensor, but I cant create new Sensor, beacuse it is virtual. Also this is not expected by me behavior. I want to create TemperatureSensor using constructor defined by Sensor ex: TemperatureSensor sensor(0xbeef/*address*/)

I want to create TemperatureSensor using constructor defined by Sensor ex: TemperatureSensor sensor(0xbeef/*address*/)
If you want to use base class constructor directly, you can use using
class TemperatureSensor: public Sensor<float> {
using Sensor::Sensor;
void collectData();
};

Related

Issue passing a reference to another class within a class

I have created the following class which has an object being passed in by reference and is implemented the following way.
Diablo_Serial_4DLib Display(&DisplaySerial);
ZenDisplay ui(Display);
class ZenDisplay
{
public:
ZenDisplay(Diablo_Serial_4DLib &display);
void setup();
private:
Diablo_Serial_4DLib* _display;
};
The constructor is straight forward and works as expected, no problem so far.
// Constructor /////////////////////////////////////////////////////////////////
ZenDisplay::ZenDisplay(Diablo_Serial_4DLib &display)
{
_display = &display;
}
I want to instantiate ZenSpeakerGroup class and pass in the same reference into it's constructor
class ZenSpeakerGroup
{
public:
ZenSpeakerGroup(Diablo_Serial_4DLib &display);
private:
Diablo_Serial_4DLib* _display;
};
ZenSpeakerGroup::ZenSpeakerGroup(Diablo_Serial_4DLib &display)
{
_display = &display;
}
I have modified the original working class to the following
class ZenDisplay
{
public:
ZenDisplay(Diablo_Serial_4DLib &display);
void setup();
private:
Diablo_Serial_4DLib* _display;
ZenSpeakerGroup _speakerGroup;
};
// Constructor /////////////////////////////////////////////////////////////////
ZenDisplay::ZenDisplay(Diablo_Serial_4DLib &display) : _speakerGroup(&display)
{
_display = &display;
}
Now I get the following error and not 100% sure what I am doing wrong.
Arduino: 1.8.16 (Mac OS X), Board: "DOIT ESP32 DEVKIT V1, 80MHz, 921600, None"
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenDisplay.cpp: In constructor 'ZenDisplay::ZenDisplay(Diablo_Serial_4DLib&)':
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenDisplay.cpp:14:78: error: no matching function for call to 'ZenSpeakerGroup::ZenSpeakerGroup(Diablo_Serial_4DLib*)'
ZenDisplay::ZenDisplay(Diablo_Serial_4DLib &display) : _speakerGroup(&display)
^
In file included from /Users/xxx/Documents/Arduino/libraries/ZenOne/ZenDisplay.h:14,
from /Users/xxx/Documents/Arduino/libraries/ZenOne/ZenDisplay.cpp:9:
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenSpeakerGroup.h:18:5: note: candidate: 'ZenSpeakerGroup::ZenSpeakerGroup(Diablo_Serial_4DLib&)'
ZenSpeakerGroup(Diablo_Serial_4DLib &display);
^~~~~~~~~~~~~~~
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenSpeakerGroup.h:18:5: note: no known conversion for argument 1 from 'Diablo_Serial_4DLib*' to 'Diablo_Serial_4DLib&'
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenSpeakerGroup.h:15:7: note: candidate: 'constexpr ZenSpeakerGroup::ZenSpeakerGroup(const ZenSpeakerGroup&)'
class ZenSpeakerGroup
^~~~~~~~~~~~~~~
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenSpeakerGroup.h:15:7: note: no known conversion for argument 1 from 'Diablo_Serial_4DLib*' to 'const ZenSpeakerGroup&'
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenSpeakerGroup.h:15:7: note: candidate: 'constexpr ZenSpeakerGroup::ZenSpeakerGroup(ZenSpeakerGroup&&)'
/Users/xxx/Documents/Arduino/libraries/ZenOne/ZenSpeakerGroup.h:15:7: note: no known conversion for argument 1 from 'Diablo_Serial_4DLib*' to 'ZenSpeakerGroup&&'
exit status 1
Error compiling for board DOIT ESP32 DEVKIT V1.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
I also tried the following with no success.
_speakerGroup = new ZenSpeakerGroup(&display)
I would appreciate some help on this.
This is the correct way of passing the display reference to ZenSpeakerGroup
ZenDisplay::ZenDisplay(Diablo_Serial_4DLib &display) : _speakerGroup(display)
{
_display = &display;
}
I have made this mistake aswell it's a typo
make sure when you want to intialize a reference define it as a refference
class ZenDisplay{
public:
ZenDisplay(Diablo_Serial_4DLib &display);
void setup();
private:
Diablo_Serial_4DLib& _display; // <--make sure this is a refference
};
now initialize the refference
ZenDisplay::ZenDisplay(Diablo_Serial_4DLib &display){
_display = display;
}

In C++ I am getting an Error while I am executing my code with get set and constructor methods [duplicate]

This question already has answers here:
Does a type require a default constructor in order to declare an array of it?
(9 answers)
Object array initialization without default constructor
(14 answers)
Closed 6 months ago.
In my code I am using the get, set and Employee constructor for getting and take the employee data for that I am creating an one .h file and two .cpp file. While executing these files i am getting error.
So my first .h file is emp.h:
#include<iostream>
class Employee
{
private:
std::string emp_Name,emp_ID,emp_Address;
public:
Employee(std::string name, std::string id, std::string address):emp_Name(name),
emp_ID(id),emp_Address(address)
{
}
void setempname(std::string name);
void setempid(std::string id);
void setempage(std::string address);
std::string getempname();
std::string getempid();
std::string getempaddress();
};
My first .cpp file is emp.cpp
#include "emp.h"
void Employee::setempname(std::string name)
{
emp_Name=name;
}
void Employee::setempid(std::string id)
{
emp_ID=id;
}
void Employee::setempage(std::string address)
{
emp_Address=address;
}
std::string Employee::getempname()
{
return emp_Name;
}
std::string Employee::getempid()
{
return emp_ID;
}
std::string Employee::getempaddress()
{
return emp_Address;
}
My second .cpp file is Main.cpp:
#include "emp.h"
int main()
{
Employee emp[2];
emp[0]= Employee ("Rohi","E345","Clk");
return 0;
}
The Error I am getting is:
g++ emp.cpp Main.cpp
Main.cpp: In function ‘int main()’:
Main.cpp:4:23: error: no matching function for call to ‘Employee::Employee()’
Employee emp[2];
^
In file included from Main.cpp:1:
emp.h:7:3: note: candidate: ‘Employee::Employee(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string)’
Employee(std::string name, std::string id, std::string address):emp_Name(name),
^~~~~~~~
emp.h:7:3: note: candidate expects 3 arguments, 0 provided
emp.h:2:7: note: candidate: ‘Employee::Employee(const Employee&)’
class Employee
^~~~~~~~
emp.h:2:7: note: candidate expects 1 argument, 0 provided
emp.h:2:7: note: candidate: ‘Employee::Employee(Employee&&)’
emp.h:2:7: note: candidate expects 1 argument, 0 provided
So Anyone please help me to solve these error.

Problems on throwing an object as an Exception: Keeping the same Constructor of parent Exception class

As my first C++ program I decided to make a simple TCP server based on previous knowledge from C and utilizing POSIX socket API:
Therefore, I made the following header file network.h:
#ifndef HTTP_NETWORK
#define HTTP_NETWORK
#include<string>
#include <arpa/inet.h>
//Dummy Value to be changed
#define MAXPENDING 5
class Exception {
public:
Exception(std::string message):message(message){}
std::string getMessage();
private:
std::string message;
};
class NetworkException:public Exception {};
class TCPServer{
public:
TCPServer(int port,std::string address);
~TCPServer();
void listen();
private:
int port;
//Socket file Descriptor
int servSock;
struct sockaddr_in ServAddr;
};
#endif
And afterwards I made and the network.cpp:
#include"network.h"
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include<iostream>
#include<cstring>
#include<string>
std::string Exception::getMessage(){
return this->message;
}
TCPServer::TCPServer(int port,std::string address)
:port(port){
if ((this->servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
throw NetworkException(std::string("SOCKET Error: could not create basic socket"));
}
memset(&this->ServAddr,0,sizeof(this->ServAddr));
ServAddr.sin_family = AF_INET;
ServAddr.sin_addr.s_addr = inet_addr(address.c_str());
ServAddr.sin_port = htons(port);
if (bind(this->servSock, (struct sockaddr *) &this->ServAddr, sizeof(this->ServAddr)) < 0) {
throw NetworkException(std::string("SOCKET Error: Failed to bind a socket"));
}
if (::listen(this->servSock, MAXPENDING) < 0) {
throw NetworkException(std::string("SOCKET Error: Failed to Listen"));
}
}
void TCPServer::listen(){
struct sockaddr_in ClntAddr; /* Client address */
socklen_t clntLen= (socklen_t)sizeof(ClntAddr);
int clntSock; /* Socket descriptor for client */
//#todo Dummy Logic Depedency Inject Socket Handler
for (;;) {
if ((clntSock = accept(servSock, (struct sockaddr *) &ClntAddr, &clntLen)) < 0) {
std::cout<<"Failed to fetch"<<std::endl;
}
send(clntSock, "12345\n", 6, 0);
std::cout << "Handling client %s\n" << inet_ntoa(ClntAddr.sin_addr) << std::endl;
close(clntSock);
}
}
TCPServer::~TCPServer(){
close(this->servSock);
}
But somehow I have hard time to throw an object as an exception:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
class NetworkException:public Exception {};
^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
./src/socket/network.cpp:31:84: error: no matching function for call to ‘NetworkException::NetworkException(std::__cxx11::string)’
throw NetworkException(std::string("SOCKET Error: Failed to bind a socket"));
^
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
class NetworkException:public Exception {};
^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
./src/socket/network.cpp:35:77: error: no matching function for call to ‘NetworkException::NetworkException(std::__cxx11::string)’
throw NetworkException(std::string("SOCKET Error: Failed to Listen"));
^
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(const NetworkException&)
class NetworkException:public Exception {};
^~~~~~~~~~~~~~~~
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const NetworkException&’
./src/socket/network.h:18:7: note: candidate: NetworkException::NetworkException(NetworkException&&)
./src/socket/network.h:18:7: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘NetworkException&&’
By first issue is that I have hard time to extend the Exception Class into something more Specific. Usually in other languages a generic class has been provided and I could be able to throw it as an exception. In C++ AFAIK any type can be thrownas an error hence I decided to have a class to be thrown.
But for now the plan backfires and I find myself hard to thow an anonymous Object of NetworkException I also tried to mitigate the issue by changing the NetworkException via:
class NetworkException:public Exception {
public:
NetworkException(std::string message){}
};
And still get errors:
In file included from ./src/main.cpp:4:0:
./src/socket/network.h: In constructor ‘NetworkException::NetworkException(std::__cxx11::string)’:
./src/socket/network.h:20:42: error: no matching function for call to ‘Exception::Exception()’
NetworkException(std::string message){}
^
./src/socket/network.h:12:5: note: candidate: Exception::Exception(std::__cxx11::string)
Exception(std::string message):message(message){}
^~~~~~~~~
./src/socket/network.h:12:5: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(const Exception&)
class Exception {
^~~~~~~~~
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(Exception&&)
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
In file included from ./src/socket/network.cpp:1:0:
./src/socket/network.h: In constructor ‘NetworkException::NetworkException(std::__cxx11::string)’:
./src/socket/network.h:20:42: error: no matching function for call to ‘Exception::Exception()’
NetworkException(std::string message){}
^
./src/socket/network.h:12:5: note: candidate: Exception::Exception(std::__cxx11::string)
Exception(std::string message):message(message){}
^~~~~~~~~
./src/socket/network.h:12:5: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(const Exception&)
class Exception {
^~~~~~~~~
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
./src/socket/network.h:10:7: note: candidate: Exception::Exception(Exception&&)
./src/socket/network.h:10:7: note: candidate expects 1 argument, 0 provided
You need to call the constructor of base class:
class NetworkException:public Exception {
public:
NetworkException(std::string message)
: Exception(message)
{}
};
before the body of ctor of derived class is performed, all data members must be constructed. Exception has only one ctor which takes string, and you have to call it explicitly.

Issue with global variable in class

With the following code, it works "correctly." Meaning it creates the foot instance of WalkerJoint.
#include <WalkerJoint.h>
class WalkerLeg {
//WalkerJoint foot;
// if this is uncommented and the below is reversed it fails
public:
WalkerLeg();
void initLeg();
};
WalkerLeg::WalkerLeg(void) {
WalkerJoint foot(2,3,4,5,6);
//foot(2,3,4,5,6);
//if uncommented with above it fails
}
void initLeg() {
Serial.print("leg init\n");
}
void setup() {
Serial.begin(115200);
while (!Serial) {}
// wait for Serial comms to become ready
}
void loop() {
int bom=0;
WalkerLeg frontLeft;
bom=0;
while(bom++<100000){}
exit(0);
}
However, I need foot to be global so other methods can use it. When I move its declaration into the Class definition it gives the following error:
/Users/bin/Documents/Arduino/WalkerLeg.cpp/WalkerLeg.cpp.ino: In constructor 'WalkerLeg::WalkerLeg()':
WalkerLeg.cpp:14: error: no matching function for call to 'WalkerJoint::WalkerJoint()'
WalkerLeg::WalkerLeg(void)
^
/Users/bin/Documents/Arduino/WalkerLeg.cpp/WalkerLeg.cpp.ino:14:26: note: candidates are:
In file included from /Users/bin/Documents/Arduino/WalkerLeg.cpp/WalkerLeg.cpp.ino:1:0:
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:23:3: note: WalkerJoint::WalkerJoint(int)
WalkerJoint(int); //for using analog inputs
^
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:23:3: note: candidate expects 1 argument, 0 provided
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:22:3: note: WalkerJoint::WalkerJoint(int, int, int, int, int)
WalkerJoint(int, int, int, int, int);
^
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:22:3: note: candidate expects 5 arguments, 0 provided
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: constexpr WalkerJoint::WalkerJoint(const WalkerJoint&)
class WalkerJoint
^
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: candidate expects 1 argument, 0 provided
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: constexpr WalkerJoint::WalkerJoint(WalkerJoint&&)
/Users/bin/Documents/Arduino/libraries/WalkerJoint.cpp/WalkerJoint.h:17:7: note: candidate expects 1 argument, 0 provided
WalkerLeg.cpp:18: error: no match for call to '(WalkerJoint) (int, int, int, int, int)'
foot(2,3,4,5,6);
^
exit status 1
no matching function for call to 'WalkerJoint::WalkerJoint()'

No matching function call call to constructor in header file

I have seen similar questions asked and tried their solutions but the answers to them do not seem to work. I have the following code:
.h
#include <iostream>
#include <vector>
#include <string>
using std::string; using std::vector;
struct DialogueNode;
struct DialogueOption {
string text;
DialogueNode *next_node;
int return_code;
DialogueOption(string t, int rc, DialogueNode * nn) : text{t},
return_code{rc}, next_node{nn} {}
};
struct DialogueNode {
string text;
vector <DialogueOption> dialogue_options;
DialogueNode();
DialogueNode(const string &);
};
struct DialogueTree {
DialogueTree() {}
void init();
void destroyTree();
int performDialogue();
private:
vector <DialogueNode*> dialogue_nodes;
};
.cpp
#include "dialogue_tree.h"
DialogueNode::DialogueNode(const string &t) : text{t} {}
void DialogueTree::init() {
string s = "Hello";
for(int i = 0; i < 5; i++) {
DialogueNode *node = new DialogueNode(s);
dialogue_nodes.push_back(node);
delete node;
}
}
void DialogueTree::destroyTree() {
}
int DialogueTree::performDialogue() {
return 0;
}
int main() {
return 0;
}
I get the error: error: no matching function for call to ‘DialogueNode:: DialogueNode(std::__cxx11::string&)’ DialogueNode *node = new DialogueNode(s);
EDIT additional notes on error
dialogue_tree.h:17:8: note: candidate: DialogueNode::DialogueNode()
dialogue_tree.h:17:8: note: candidate expects 0 arguments, 1 provided
dialogue_tree.h:17:8: note: candidate: DialogueNode::DialogueNode(const DialogueNode&)
dialogue_tree.h:17:8: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘const DialogueNode&’
dialogue_tree.h:17:8: note: candidate: DialogueNode::DialogueNode(DialogueNode&&)
dialogue_tree.h:17:8: note: no known conversion for argument 1 from ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘DialogueNode&&’
Which makes no sense to me because I have the constructor defined to take a string as an argument.
You've declared your constructor as:
DialogueNode(const string);
But defined it as:
DialogueNode(const string &t);
Those two aren't the same; the former takes a const string while the latter takes a const string reference. You'll have to add the & to specify a reference argument:
DialogueNode(const string &);
it is because in the constructor you are specifying that the parameter will be a string of constant type and when creating an object you are passing a string. The type mismatch is the problem, either fix the constructor parameter to string or change when you are creating an object.