unique_ptr<> causes compliation errors in C++ - c++

I am using this library: https://github.com/Agamnentzar/bluetooth-serial-port
BTSerialPortBinding::Create(address, channelID)
Returns new instance of BTSerialPortBinding object
address: string containint bluetooth address of the device
channelID: ID of the serial port channel
I have a statement:
unique_ptr<BTSerialPortBinding>bt(BTSerialPortBinding::Create(d1.address, 1));
When I separate the statement with the declaration in ArduinoDevice.h and initialisation in ArduinoDevice.cpp in constructor like so:
std::unique_ptr<BTSerialPortBinding> bt;
bt.reset(BTSerialPortBinding::Create("93:83:, 1));
When I added these statements I got the following error:
ArduinoDevice &ArduinoDevice::operator =(const ArduinoDevice &)': attempting to reference a deleted function
Relevant bit in Process.cpp file which is referenced by the error
dev = ArduinoDevice("/dev/tty.IP-DevB");
Process.h
#ifndef __PROCESS_H
#define __PROCESS_H
#define _USE_MATH_DEFINES
#include "ResonantLowpassFilter.h"
#include "ArduinoDevice.h"
//==============================================================================
/**
*/
class AudioProcessor : public AudioProcessor
{
public:
//==============================================================================
WahwahAudioProcessor();
~WahwahAudioProcessor();
void prepareToPlay (double sampleRate, int samplesPerBlock);
void releaseResources();
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
AudioProcessorEditor* createEditor();
int getNumParameters();
int getNumPrograms();
int getCurrentProgram();
void setCurrentProgram (int index);
const String getProgramName (int index);
void changeProgramName (int index, const String& newName);
float centreFrequency_, q_;
void updateFilterArduino();
ArduinoDevice dev; //instance to an Arduino device from which sensor data is read
};
#endif // _PROCESS
ArduinoDevice.h
#ifndef ArduinoDevice_h
#define ArduinoDevice_h
#include <stdio.h>
#include "BTSerialPortBinding.h"
#include <memory>
class ArduinoDevice
{
public:
ArduinoDevice(const char *dev="");
void connect();
void start(void);
void stop(void);
void read(void);
/**
Disconnects from Arduino device
**/
~ArduinoDevice();
private:
const char *device; //port address of the device (e.g. "/dev/tty.FireFly-E552-SPP")
std::unique_ptr<BTSerialPortBinding> bt; //bt serial port
void close(void);
};
#endif
Edit:
I am using Windows 10, Visual Studio 2015 and Microsoft's C++ Compiler. I am also using an extra JUCE library(https://www.juce.com/).
dev = ArduinoDevice("/dev/tty.IP-DevB"));
dev is declared in the Process.h file above its an instance of ArduinoDevice
My constructor looks like this:
ArduinoDevice::ArduinoDevice(const char *dev)
{
device = dev;
bt.reset(BTSerialPortBinding::Create("98:D3:31:FD:11:1A", 1));
}
I've now tried this in ArduinoDevice.cpp and declaration .h but I still get the same error as above:
ArduinoDevice&&(const char *dev);
{
data = dev.data;
dev.data = nullptr;
}

unique_ptr is not copyable. So when you declare it as a member of your class, your class becomes non-copyable too. The error exactly points that out. (Copy assignment operator is deleted because of that).
Note that usually the move assignment operator is automatically generated by the compiler for you. But in your case since you've explicitly defined a destructor for your class, compiler cant safely define a move assignment operator (or constructor) for you.

Related

When assigning value to a member function pointer, the assignment tampered with other data

Before the assignment operation, the member variable u works fine, see figure 1
After the assignment operation, the data of the member variable u is tampered, see figure 2
Continuing resize operation will trigger an error: read access violation, see figure 3
The development environment is win10 Visual Studio Community 2022 17.0.4 x64 in Debug mode
Compiling by mingw does not show this problem and the code runs smoothly. I suspect it's a bug for msvc. In addition, this error is very strange, if merged the 4 code files, this error may or may not disappear, which is related to the code order.
Below is the complete code
test.h
#pragma once
class ETEST {
public:
ETEST() {};
void add() {};
};
order.h
#pragma once
#include <vector>
class ETEST;
class First {
public:
First(const char*);
void (ETEST::* add)();
std::vector<double> u, v;
};
class Second : public First {
public:
Second(const char*);
};
first.cpp
#include "test.h"
#include "order.h"
First::First(const char*) :
add(NULL), u{}, v{} {
};
int main(int argc, char* argv[]) {
Second chk("");
return 0;
}
second.cpp
#include "order.h"
#include "test.h"
#include <cstdio>
Second::Second(const char*) :
First(NULL) {
add = &ETEST::add;
u.resize(10, 0.0);
printf("u resize sucess!\n");
};
Below are my actions:
1.create new solution
2.add code files
3,paste the code
4.Debugging, it throws an exception
(I did not modify any solution properties, all use the default settings)

Arduino C++ file - class instantiation fails when setting a private member variable in the constructor

I'm using the Arduino IDE 1.0.5-r2 and trying to create a class with two member variables, _pinA and _pinB. When I call the constructor from my Arduino sketch, I get this error:
RotaryEncoderReader.cpp:6: error: request for member '_pinB' in 'this', which is of non-class type 'RotaryEncoderReader* const'
The constructor can be called from a regular C++ files compiled using GCC, and there are no errors. Am I missing something about how to use a class constructor with an Arduino?
Here is the class header:
#ifndef RotaryEncoderReader_h
#define RotaryEncoderReader_h
#include "Arduino.h"
class RotaryEncoderReader {
private:
int _pinA;
int _pinB;
volatile long encoderPos;
public:
RotaryEncoderReader( int newPinA, int newPinB );
void doEncoderA();
void doEncoderB();
long getPosition();
};
#endif
Here's the implementation:
#include "RotaryEncoderReader.h"
RotaryEncoderReader::RotaryEncoderReader( int newPinA, int newPinB )
: _pinA(newPinA),
_pinB(newPinB),
encoderPos(0)
{
}
void RotaryEncoderReader::doEncoderA()
{
//Irrelevant
}
void RotaryEncoderReader::doEncoderB()
{
//Irrelevant
}
long RotaryEncoderReader::getPosition()
{
return _pinA + _pinB;
}
And here's the Arduino sketch:
#include <RotaryEncoderReader.h>
int pinA = 2;
int pinB = 3;
RotaryEncoderReader reader(pinA, pinB);
void setup()
{
}
void loop()
{
}

Why doesn't Xcode recognize free() and malloc() in this .cpp file?

I have many .cpp files in my project that work. But this one irritates Xcode or the compiler.
It doesn't recognise free() and malloc() but this is also C. What can be wrong?
Header ssdpmessage.h looks like this:
#ifndef _SSDPMESSAGE_H
#define _SSDPMESSAGE_H
#include "ssdptools.h"
#include <vector>
#include <arpa/inet.h>
#include "ssdpdb.h"
class SSDPMessage{
public:
SSDPMessage();
virtual ~SSDPMessage();
//What type of message can we handle
virtual SSDP_TYPE GetType()=0;
//Get the message dignature implemented in this class
virtual std::vector<SSDP_HTTP_HEADER*> GetHeaderSignature();
//Can this class parse the message with this signature ?
virtual u8 CanProcess(std::vector<SSDP_HTTP_HEADER*> msgheaders);
//Process the message, return value:
//0 : processed
//1 : not for me, search for another to process
//<0 : message was for me but there is an error
virtual int Process(struct sockaddr* sender, std::vector<SSDP_HTTP_HEADER*> msgheaders)=0;
//ReInit all members
virtual void ReInit()=0;
virtual SSDPDB* GetDB();
virtual void SetDB(SSDPDB* db);
private:
std::vector<SSDP_HTTP_HEADER*> mHeaderSignature;
protected:
int AddSignatureHeader(char* fieldname, char* fieldvalue);
SSDPDB *mDB;
private:
SSDPMessage(const SSDPMessage &src);
SSDPMessage& operator= (const SSDPMessage &src);
};
#endif //_SSDPMESSAGE_H
The includes and affected code in ssdpmessage.cpp look like this:
#include "ssdpmessage.h"
SSDPMessage::SSDPMessage():mDB(NULL){
}
SSDPMessage::~SSDPMessage(){
std::vector<SSDP_HTTP_HEADER*>::iterator it;
for(it=mHeaderSignature.begin(); it<mHeaderSignature.end(); it++){
free(*it);
}
mHeaderSignature.clear();
}
int SSDPMessage::AddSignatureHeader(char* fieldname, char* fieldvalue){
SSDP_HTTP_HEADER *thisHeader = (SSDP_HTTP_HEADER*)malloc(sizeof(SSDP_HTTP_HEADER));
thisHeader->fieldname = (u8*)fieldname;
thisHeader->fieldnamelen = strlen(fieldname);
thisHeader->fieldvalue = (u8*)fieldvalue;
thisHeader->fieldvaluelen = strlen(fieldvalue);
mHeaderSignature.push_back(thisHeader);
return mHeaderSignature.size();
}
This is code from the upnpx library. It works without problem in the demo project of the library.
malloc requires you to include cstdlib.

Why does compiler tries to pass a pointer to reference rather than pointer in this code snippet?

I have 5 files:
ExecutionStrategyInterface.h
ExecutorInterface.h
TaskCollectionInterface.h
TaskExecutor.h
TaskExecutor.cpp.
TaskExecutor implements the following member method:
void TaskExecutor::execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) {
es.execute(tci);
}
At compile time, the compiler calls a member method with a parameter of type pointer to a reference(i.e: mylib::core::TaskCollectionInterface*&).
TaskExecutor.cpp: In member function ‘virtual void mylib::core::TaskExecutor::execute(mylib::core::TaskCollectionInterface*, const mylib::core::ExecutionStrategyInterface&)’:
TaskExecutor.cpp:16: error: no matching function for call to ‘mylib::core::ExecutionStrategyInterface::execute(mylib::core::TaskCollectionInterface*&) const’
./././ExecutionStrategyInterface.h:24: note: candidates are: virtual void mylib::core::ExecutionStrategyInterface::execute(TaskCollectionInterface*) const
make: *** [TaskExecutor.o] Error 1
Can anyone explain me what is happening here please ?
Classes:
ExecutionStrategyInterface.h
#ifndef _EXECUTIONSTRATEGYINTERFACE_H_
#define _EXECUTIONSTRATEGYINTERFACE_H_
class TaskCollectionInterface;
namespace mylib { namespace core {
/**
* Interface for executing a strategy.
*/
class ExecutionStrategyInterface {
public:
/**
* Executes a strategy
*/
virtual void execute(TaskCollectionInterface* tci) const = 0;
};
}} // namespaces
#endif // _EXECUTIONSTRATEGYINTERFACE_H_
TaskCollectionInterface.h
#ifndef _TASKCOLLECTIONINTERFACE_H_
#define _TASKCOLLECTIONINTERFACE_H_
#include "./ExecutionStrategyInterface.h"
namespace mylib { namespace core {
/**
* Interface for a collection of tasks.
*/
class TaskCollectionInterface {
public:
~TaskCollectionInterface();
};
}} // namespaces
#endif // _TASKCOLLECTIONINTERFACE_H_
ExecutorInterface.h
#ifndef _EXECUTORINTERFACE_H_
#define _EXECUTORINTERFACE_H_
class ExecutionStrategyInterface;
class TaskCollectionInterface;
#include "./ExecutionStrategyInterface.h"
#include "./TaskCollectionInterface.h"
namespace mylib { namespace core {
/**
* Interface for an executor.
*/
class ExecutorInterface {
public:
virtual void execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) = 0;
~ExecutorInterface();
};
}} // namespaces
#endif // _EXECUTORINTERFACE_H_
TaskExecutor.h
#ifndef _TASKEXECUTOR_H_
#define _TASKEXECUTOR_H_
#include "./ExecutorInterface.h"
class TaskCollectionInterface;
class ExecutionStrategyInterface;
namespace mylib { namespace core {
/**
* Task Runner.
*/
class TaskExecutor: public ExecutorInterface {
public:
virtual void execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) = 0;
};
}} // namespaces
#endif // _TASKEXECUTOR_H_
TaskExecutor.cpp
#include "./TaskExecutor.h"
#include "./ExecutionStrategyInterface.h"
#include "./TaskCollectionInterface.h"
namespace mylib { namespace core {
void TaskExecutor::execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) {
es.execute(tci);
}
}} // namespaces
This is confusing because you are forward-declaring the class outside the namespace, so you are ending up with two different classes with the same name. You'll want something like this instead:
namespace mylib {
namespace core {
class TaskCollectionInterface;
class ExecutionStrategyInterface {
.
.
.
};
}
}
The way you have it now, your execute method is taking a pointer to ::TaskCollectionInterface instead of mylib::core::TaskCollectionInterface.
When gcc says type&, it's just its shorthand for saying that you are passing an lvalue so that you know that functions taking a non-const reference are viable candidates.
The problem that you have is that you have declared the method as taking a ::TaskCollectionInterface, but the error message indicates that you are attempting to pass a ::mylib::core::TaskCollectionInterface.
You have a declaration of ::mylib::core::TaskCollectionInterface in TaskCollectionInterface.h that masks the declaration of ::TaskCollectionInterface in the namespace mylib::core.
This is because you are passing a pointer TaskCollectionInterface* tci to the ExecutionStrategyInterface::execute method, while it wants a reference. So you have to dereference that pointer when passing it to that function:
void TaskExecutor::execute(TaskCollectionInterface* tci, const ExecutionStrategyInterface& es) {
es.execute(*tci);
}

C++ forward declaration error

I have an error that goes like this
In file included from Level.hpp:12,
from main.cpp:4:
Corridor.hpp: In method `void Game::Corridor::update()':
Corridor.hpp:41: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor.hpp:42: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor.hpp:43: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor.hpp:44: invalid use of undefined type `class Game::Level'
Corridor.hpp:13: forward declaration of `class Game::Level'
Corridor and Level are ...
// Corridor.hpp
#ifndef GAME_CORRIDOR_HPP
#define GAME_CORRIDOR_HPP
#include <Moot/Math.hpp>
//#include <Level.hpp>
#include <GameWindow.hpp>
namespace Game
{
class Level; // <-- LINE 13
class Corridor
{
static const unsigned int defaultLevelDepth = 800;
Moot::Math::Vector3D wp1, wp2, wp3, wp4;
Moot::Math::Vector2D sp1, sp2, sp3, sp4;
Level * p_level;
public:
Corridor(Moot::Math::Vector3D setFirstPoint, Moot::Math::Vector3D setSecondPoint)
{
wp1 = setFirstPoint;
wp2 = setSecondPoint;
wp3 = setFirstPoint;
wp3.z += defaultLevelDepth;
wp4 = setSecondPoint;
wp4.z += defaultLevelDepth;
}
void update() {
sp1 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp1); // <- LINE 41 etc.
sp2 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp2);
sp3 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp3);
sp4 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp4);
//p_level->getLevelCamera();
}
void draw()//const
{
Moot::Color tempColor;
windowInstance().graphics().drawQuad( sp1.x, sp1.y, tempColor,
sp2.x,sp2.y, tempColor,
sp3.x, sp3.y, tempColor,
sp4.x,sp4.y, tempColor, 1);
}
void setLevel(Level* setLevel) {
p_level = setLevel;
}
};
}
#endif
and
// Level.hpp
#ifndef GAME_LEVEL_HPP
#define GAME_LEVEL_HPP
#include <Moot/Forward.hpp>
#include <Moot/Window.hpp>
#include <Moot/Math.hpp>
#include <GameWindow.hpp>
#include <Camera.hpp>
#include <Corridor.hpp>
#include <Player.hpp>
#include <vector>
namespace Game
{
class Level
{
typedef Corridor* p_corridor;
typedef std::vector<p_corridor> CorridorList;
typedef CorridorList::reverse_iterator ReverseCorridorItter;
CorridorList m_map;
Camera m_camera;
Player m_player;
public:
Level()
{
m_player.setLevel(this);
// Lots of vertices being defined into m_map.
// Loop through and set camera
ReverseCorridorItter rit;
for(rit = m_map.rbegin(); rit != m_map.rend(); rit++)
(*rit)->setLevel(this);
}
~Level()
{
ReverseCorridorItter rit;
for(rit = m_map.rbegin(); rit != m_map.rend(); rit++)
delete (*rit);
m_map.clear();
}
void update()
{
// Temp delete when input and player are implimented.
if(pad[0].buttons & PAD_UP)
m_camera.updateTargetOffsets(0, -2);
if(pad[0].buttons & PAD_DOWN)
m_camera.updateTargetOffsets(0, 2);
if(pad[0].buttons & PAD_LEFT)
m_camera.updateTargetOffsets(-2, 0);
if(pad[0].buttons & PAD_RIGHT)
m_camera.updateTargetOffsets(2, 0);
m_player.update();
ReverseCorridorItter rit;
for (rit = m_map.rbegin(); rit != m_map.rend(); rit++)
(*rit)->update();
}
void draw() // const // EH!!! wtf ReverseIter isn't a member
{
m_player.draw();
ReverseCorridorItter rit;
for (rit = m_map.rbegin(); rit != m_map.rend(); rit++)
(*rit)->draw();
}
Camera& getLevelCamera() {
return m_camera;
}
};
}
#endif
The pointer is being set as far as I can tell, but when I try to access a function from Level, BOOM!
Thanks.
PS: The compiler is gcc 2.95.2 if that makes a difference.
EDIT
Updated with complete code.
You are #include-ing Level's complete declaration:
#include <Level.hpp>
...and then you try to forward-declare Level:
namespace Game
{
class Level;
Don't do this. Choose one or the other. (edit) Or at least put the forward-declaration before the #include-ion of the complete declaration. If all you're doing in game_corridor.hpp is setting pointers to a Level, then a forward declare should do fine. If however you need to call functions on Level from within the HPP file, then you'll need to #include the complete declaration.
EDIT2:
Based on your clarifying edit to your OP, you must #include the complete declaration of Level, and not try to use a forward declaration.
If you forward-declare Game::Level then don't #include it. In a not-so-related note, use #include "header.hpp", not #include <header.hpp>.
Edit as per your updates: Bring the definition of Game::Corridor::update() outside the header and into an implementation file. This way the compile need not know anything about Game::Level apart from the fact that it exists and it's a type.
The problem is that Corridor doesn't know what a Level is, because it can't really #include Level.hpp, because Level.hpp is what #included Corridor.hpp.
The underlying problem is that you're trying to #include a source file. The really underlying problem is that you're using #include when you haven't separated your code into source files and header files. Here's how to split it up. (I'm assuming you're familiar with compiling source files into object files, then linking them into executables.)
Corridor.hpp:
#ifndef GAME_CORRIDOR_HPP
#define GAME_CORRIDOR_HPP
#include <Moot/Math.hpp>
#include <Level.hpp>
namespace Game
{
class Level;
class Corridor
{
static const unsigned int defaultLevelDepth = 800;
Moot::Math::Vector3D wp1, wp2, wp3, wp4;
Moot::Math::Vector2D sp1, sp2, sp3, sp4;
Level * p_level;
public:
Corridor(Moot::Math::Vector3D setFirstPoint, Moot::Math::Vector3D setSecondPoint);
void update();
void draw();
void setLevel(Level* setLevel);
};
}
#endif
Corridor.cpp:
#include "Corridor.hpp"
namespace Game
{
Corridor::Corridor(Moot::Math::Vector3D setFirstPoint, Moot::Math::Vector3D setSecondPoint)
{
wp1 = setFirstPoint;
wp2 = setSecondPoint;
wp3 = setFirstPoint;
wp3.z += defaultLevelDepth;
wp4 = setSecondPoint;
wp4.z += defaultLevelDepth;
}
void Corridor::update()
{
sp1 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp1);
sp2 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp2);
sp3 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp3);
sp4 = p_level->getLevelCamera().convert3DVectorWithScreenAlgorithm(wp4);
}
// and so on
}