I was trying to share a mutex between threads to share a queue. I have a messenger class that will be sending the messages and in the header I declared my constructor like so:
class Messenger {
public:
Messenger(std::mutex& m);
Messenger();
std::mutex& mutex;
private:
//variables
zmq::context_t zmq_context;
zmq::socket_t zmq_socket;
};
and the corresponding c++ is
/**
* Blank constructor
*/
Messenger::Messenger(){
}
Messenger::Messenger(std::mutex& m) :
zmq_context(1),
zmq_socket(zmq_context, ZMQ_PUB),
mutex(m)
{
}
Then in my main application code I give it the mutex and instantiate it like so:
//start code
std::mutex mutex;
auto msgr = std::make_unique<Messenger>(std::ref(mutex));
This will compile but throws a linker error complaining about an undefined reference to `Messenger::Messenger(std::mutex&)'
/usr/bin/ld: CMakeFiles/ImuStream.dir/imu_stream.cpp.o: in function `std::_MakeUniq<Messenger>::__single_object std::make_unique<Messenger, std::reference_wrapper<std::mutex> >(std::reference_wrapper<std::mutex>&&)':
imu_stream.cpp:(.text._ZSt11make_uniqueI9MessengerJSt17reference_wrapperISt5mutexEEENSt9_MakeUniqIT_E15__single_objectEDpOT0_[_ZSt11make_uniqueI9MessengerJSt17reference_wrapperISt5mutexEEENSt9_MakeUniqIT_E15__single_objectEDpOT0_]+0x41): undefined reference to `Messenger::Messenger(std::mutex&)'
collect2: error: ld returned 1 exit status
However if I change the declaration to this:
class Messenger {
public:
//Messenger(std::mutex& m);
Messenger(std::mutex& m) : mutex(m) {};
Messenger();
std::mutex& mutex;
private:
//variables
zmq::context_t zmq_context;
zmq::socket_t zmq_socket;
};
Then it links just fine. Why is that? And why isn't the linker mad that I did not put zmq_context or zmq_socket in the class definition?
Thank you.
---adding compiling method---- I'm using cmake to compile, this is my cmake file:
cmake_minimum_required(VERSION 3.10)
# set the project name
project(ImuStream VERSION 1.0)
#configure header for setting the version
configure_file(ImuStreamConfig.h.in ImuStreamConfig.h)
# add the executable
add_executable(ImuStream imu_stream.cpp)
#find cppzmq wrapper, installed by make of cppzmq
find_package(cppzmq)
target_link_libraries(ImuStream cppzmq)
target_include_directories(ImuStream PUBLIC
"${PROJECT_BINARY_DIR}"
)
I just make a build folder, do a cmake .. and then a make. Looks like I forgot to add Messenger.cpp to my cmake file :(