I am getting attempting to reference a deleted function error which I feel is because of inter dependency between classes.
Location.h
#ifndef A_LOCATION_H
#define A_LOCATION_H
struct location {
double lat;
double lon;
double alt;
};
#endif //A_LOCATION_H
P.h
#ifndef A_P_H
#define A_P_H
#include <vector>
#include <mutex>
#include <memory>
#include "Location.h"
class C;
class P {
std::vector<std::shared_ptr<C>> C_List;
struct location loc {};
public:
P() = default;
~P() = default;
std::mutex mut;
void add_child(const std::string& th_name);
void del();
void set_data(double lat, double lon, double alt);
struct location get_data();
};
#endif //A_P_H
P.cpp
#include <iostream>
#include "C.h"
#include "P.h"
void P::add_child(const std::string& th_name) {
std::lock_guard<std::mutex> lg(mut);
auto& ref = C_List.emplace_back(std::make_shared<C>());
ref->set_name(th_name);
ref->set_P(this);
ref->start();
}
void P::del() {
std::lock_guard<std::mutex> lg(mut);
for (auto& c : C_List)
c->terminate = true;
for (auto& c : C_List)
c->wait();
C_List.clear();
}
struct location P::get_data() {
std::lock_guard<std::mutex> lg(mut);
return loc;
}
void P::set_data(double lat, double lon, double alt) {
std::lock_guard<std::mutex> lg(mut);
loc.lat = lat;
loc.lon = lon;
loc.alt = alt;
}
C.h
#ifndef A_C_H
#define A_C_H
#include <string>
#include <thread>
#include <chrono>
#include <atomic>
class P;
class C {
P *p {};
std::string name {};
std::thread th {};
struct location loc {};
void run();
public:
C() = default;
~C() = default;
void set_P(P* p);
void set_name(const std::string& name);
void start();
void wait();
std::atomic<bool> terminate {false};
};
#endif //A_C_H
C.cpp
#include <iostream>
#include "P.h"
#include "C.h"
void C::run() {
while (!terminate) {
std::cout << name << std::endl;
{
auto loc = p->get_data();
// perform calculation based on P's object location, and it's current location
}
using namespace std::chrono_literals;
std::this_thread::sleep_for(1s);
}
}
void C::set_P(P* p) {
this->p = p;
}
void C::set_name(const std::string& name) {
this->name = name;
}
void C::start() {
th = std::thread(&C::run, this);
}
void C::wait() {
th.join();
}
Main.cpp
#include <iostream>
#include "P.h"
int main() {
P p = P();
p.add_child("C1");
p.add_child("C2");
p.add_child("C3");
char input;
std::cin >> input;
p.del();
}
Also there exists a kind of deadlock that will happen when del function of P's object gets called. I am not getting how to resolve this issue?
This is the short description of the error I'm getting
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\include\xmemory(671): error C2280: 'C::C(const C &)': attempting to reference a deleted function
C:\Users\HARSHA\Desktop\LC\2022\A\C.h(33): note: compiler has generated 'C::C' here
C:\Users\HARSHA\Desktop\LC\2022\A\C.h(33): note: 'C::C(const C &)': function was implicitly deleted because a data member invokes a deleted or inaccessible function 'std::thread::thread(const std::thread &)'
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\14.26.28801\include\thread(93): note: 'std::thread::thread(const std::thread &)': function was explicitly deleted
std::thread, std::atomic, std::mutex types are not copyable, so the compiler cannot produce the default copy-constructors and copy-asignments.
You must write your own copy constructors for C and P classes.
P(P const& arg){ ... do stuff ... }
Related
How do I make Singleton generic template,
and how can I test it?
Right now I am interested in seeing with my own eyes that 2 threads that invoke get_instance() will get the same pointer to the same singleton.
// g++ singleton.cpp -std=c++2a -pthread -o singleton
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>
#include <chrono>
#include <pthread.h>
#include <future>
using namespace std;
template <class T>
struct Singleton
{
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
static T &get_instance()
{
static T _{allow()};
return _;
}
private:
struct allow
{
};
protected:
Singleton(allow) {}
};
class A : public Singleton<A>
{
using Singleton<A>::Singleton;
// Rest of functionality for class A
};
int main()
{
auto &x = Singleton<A>::get_instance();
auto &y = A::get_instance();
printf("%p\n", &x);
printf("%p\n", &y);
void *p1;
void *p2;
// thread worker1(Singleton<A>::get_instance);
// thread worker2(Singleton<A>::get_instance);
// worker1.join();
// worker2.join();
printf("%p\n", p1);
printf("%p\n", p2);
// compiler error
// auto z = A();
}
I'm using c++ 14. Why isn't googletest able to pick up the curl_client class object pointer? Did I initialize it correctly in CurlClientTest?
Testing code:
#include "../src/include/CurlClient.h"
#include <gtest/gtest.h>
#include <string>
class CurlClientTest : testing::Test {
public:
SimpleCURLClient::CurlClient *curl_client;
virtual void SetUp() {
curl_client = new SimpleCURLClient::CurlClient(test_url);
}
virtual void TearDown() {
delete curl_client;
}
private:
std::string test_url = "http://postman-echo.com/get?foo1=bar1&foo2=bar2";
};
TEST(CurlClientTest, CurlClientInitTest) {
std::cout << curl_client->getCurlUrl << "\n";
}
code for CurlClient.h:
#include <curl/curl.h>
#include <exception>
#include <iostream>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
#ifndef UTILS_CURLCLIENT_H
#define UTILS_CURLCLIENT_H
namespace SimpleCURLClient {
class CurlClient {
public:
CurlClient(std::string remote_url, int ip_protocol = 1, int timeout = 10,
bool follow_redirects = 1);
~CurlClient();
void setCurlUrl(std::string &new_url);
std::string getCurlUrl();
void setOption(CURLoption curl_option_command, long curl_option_value);
void setOption(CURLoption curl_option_command, std::string curl_option_value);
void setHeader(std::vector<std::string> &header_list);
std::pair<CURLcode, std::string> makeRequest();
std::pair<CURLcode, std::string> makeRequest(std::string &post_params);
std::pair<CURLcode, std::string> sendGETRequest();
std::pair<CURLcode, std::string> sendPOSTRequest(std::string &post_params);
std::pair<CURLcode, std::string> sendDELETERequest(std::string &post_params);
private:
std::string m_curl_url;
CURL *m_curl;
struct curl_slist *m_curl_header_list;
};
} // namespace SimpleCURLClient
#endif // UTILS_CURLCLIENT_H
Error:
Build FAILED.
"E:\somepath\simple_curl_cpp\build\test\simple_curl_cpp_test.vcxproj" (default target) (1) ->
(ClCompile target) ->
E:\somepath\simple_curl_cpp\test\CurlClientTest.cc(21): error C2065: 'curl_client': undeclared identifier [E:\somepath\simple_curl_cpp\build\test\simple_curl_cpp_test.vcxproj]
E:\somepath\simple_curl_cpp\test\CurlClientTest.cc(21): error C2227: left of '->getCurlUrl' must point to class/struct/union/generic type [E:\somepath\simple_curl_cpp\build\test\simple_curl_cpp_test.vcxproj]
ANSWER (GIVEN BY Chris Olsen in comments) :
We have to use TEST_F and NOT TEST. Also change CurlClientTest to public. The below code for the test works.
#include "../src/include/CurlClient.h"
#include <gtest/gtest.h>
#include <string>
class CurlClientTest : public testing::Test {
public:
SimpleCURLClient::CurlClient *curl_client;
virtual void SetUp() {
curl_client = new SimpleCURLClient::CurlClient(test_url);
}
virtual void TearDown() {
delete curl_client;
}
private:
std::string test_url = "http://postman-echo.com/get?foo1=bar1&foo2=bar2";
};
TEST_F(CurlClientTest, CurlClientInitTest) {
std::cout << curl_client->getCurlUrl() << "\n";
}
Tests using fixtures require use of the TEST_F macro. See Test Fixtures in the Google Test Primer for more info.
TEST_F(CurlClientTest, CurlClientInitTest) {
std::cout << curl_client->getCurlUrl << "\n";
}
This question already has answers here:
Adding Elements to std::vector of an abstract class
(4 answers)
Closed 5 years ago.
I have a problem with my code.
I have three classes, and one of them is a pure abstract class. I don't know why I receive the error:
'note' cannot instantiate abstact class.
It may be because of STL usage, or I have made a mistake and I dont see it.
The problem is I tried without STL and it works, and I don't know what is the problem here because I think it it correct.
#pragma once
class note
{
protected:
int ziua;
int ora;
public:
note();
note(int day,int hour);
virtual void print()=0;
virtual ~note();
};
#include "note.h"
note::note()
{
}
note::note(int day, int hour) :ziua(day), ora(hour)
{
}
note::~note()
{
}
#pragma once
#include "note.h"
#include <iostream>
class apeluri:public note
{
char *numar_telefon;
public:
apeluri();
apeluri(int day, int h, char*phone);
void print()
{
printf("%d %d %s", ziua, ora, numar_telefon);
}
~apeluri();
};
#pragma once
#include <iostream>
#include "apeluri.h"
#include <vector>
#include "note.h"
using namespace std;
class remainder
{
vector<note> t;
public:
remainder();
void addsedinta(int zi, int ora, int durata, char*subi);
void addapel(int zi, int ora, char*phon)
{
apeluri *f;
f = new apeluri(zi, ora, phon);
t.push_back(*f);
}
void show()
{
}
~remainder();
};
In your remainder class, using vector<note> is illegal. note is abstract, so the vector can't create note objects.
Even if note were not abstract, your code would still not work correctly, because it would be affected by object slicing.
To store derived objects in a container of base classes, you must use pointers instead, ie vector<note*>:
#pragma once
#include <iostream>
#include <vector>
#include "note.h"
#include "apeluri.h"
using namespace std;
class remainder
{
private:
vector<note*> t;
remainder(const remainder &) {}
remainder& operator=(const remainder &) { return *this; }
public:
remainder();
~remainder()
{
for(std::vector<note*>::iterator i = t.begin(); i != t.end(); ++i) {
delete *i;
}
}
void addsedinta(int zi, int ora, int durata, char*subi);
void addapel(int zi, int ora, char*phon)
{
apeluri *f = new apeluri(zi, ora, phon);
t.push_back(f);
}
void show()
{
}
};
If you are using C++11 or later, this would be better written as this instead:
#pragma once
#include <iostream>
#include <vector>
#include <memory>
#include "note.h"
#include "apeluri.h"
using namespace std;
class remainder
{
private:
vector<unique_ptr<note>> t;
public:
remainder();
remainder(const remainder &) = delete;
remainder& operator=(const remainder &) = delete;
void addsedinta(int zi, int ora, int durata, char*subi);
void addapel(int zi, int ora, char*phon)
{
t.push_back(std::unique_ptr<apeluri>(new apeluri(zi, ora, phon)));
// in C++14 and later, use this instead:
// t.push_back(std::make_unique<apeluri>(zi, ora, phon));
}
void show()
{
}
};
I have the following files.
a.h:
#ifndef __A__
#define __A__
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class A: public boost::enable_shared_from_this<A>{
public:
void somefunction();
};
#endif
a.cpp:
#include "a.h"
#include "b.h"
void A::somefunction()
{
Node new_node;
new_node.id_ = 1;
new_node.ptr = shared_from_this();
C* c = C::GetInstance();
c->addNode(new_node);
}
b.h:
#ifndef __B__
#define __B__
#include "a.h"
#include <vector>
typedef boost::shared_ptr<A> a_ptr;
struct Node{
size_t id_;
a_ptr ptr;
};
class C {
public:
static C *GetInstance(){
if(m_pInstance == nullptr){
m_pInstance = new C();
}
return m_pInstance;
}
void addNode(Node& node);
void show();
private:
static C* m_pInstance;
std::vector<Node> nodes_;
};
#endif
b.cpp:
#include "b.h"
#include <iostream>
C* C::m_pInstance = nullptr;
void C::addNode(Node& node){
nodes_.push_back(node);
}
void C::show(){
for(size_t i=0; i< nodes_.size(); i++){
if(nodes_[i].ptr != nullptr)
std::cout << nodes_[i].id_ << " " << "pointer not null" << std::endl;
}
}
main.cpp:
#include "a.h"
#include "b.h"
int main(){
A a_tmp;
a_tmp.somefunction();
C* c_tmp = C::GetInstance();
c_tmp->show();
return 0;
}
What I want to do is to use a struct to store the pointer of class A instance. But I cannot resolve the relationship between these files. Can someone give me some ideas ?
UPDATE:
The problem is, when I compile these files. I got
In b.h, error: ‘A’ was not declared in this scope typedef boost::shared_ptr<A> a_ptr;
UPDATE:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
A a_tmp;
a_tmp.somefunction();
This will not work. Since A::someFunction calls shared_from_this, there must exist at least one shared_ptr to any A object on which you call someFunction. Change this to:
boost::shared_ptr<A> a_tmp(boost::make_shared<A>());
a_tmp->someFunction();
I'm new with the Boost library, and I got a problam a bit complex for me.
I tried to reformulate it with an example found in previous question that might fit well my problem.
(The previous question is here)
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
: public boost::enable_shared_from_this<Base>,
private boost::noncopyable
{
public:
virtual void test() = 0;
protected:
virtual void foo(int i) = 0;
};
class Derived
: public Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
std::map<int, int> data;
public:
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
std::for_each(data.begin(), data.end(),
boost::bind(&Derived::foo, shared_from_this(),
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
std::set<Base_ptr> Bases_;
Base_ptr derived(new Derived());
Bases_.insert(derived);
derived->test();
return 0;
}
I have a base object which is contained in a set, and different derived objects (in this example, only one).
The derived object should call his own protected method with a boost::bind.
In the real problem, the boost::bind generate a callback method for an asynchronous operation, it's why (I think) I need a shared_ptr.
Otherwise, using the pointer this instead of shared_from_this() resolve the problem.
When I compile this code, I got a long error message ended with (which I think is the most significant part):
bind_test.cpp:43:78: instantiated from here
/usr/include/boost/bind/mem_fn_template.hpp:156:53: error: pointer to member type ‘void (Derived::)(int)’ incompatible with object type ‘Base’
/usr/include/boost/bind/mem_fn_template.hpp:156:53: error: return-statement with a value, in function returning 'void'
I tried to manage with more inheritance from enable_shared_from_this, and some static cast :
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
: public boost::enable_shared_from_this<Base>,
private boost::noncopyable
{
public:
virtual void test() = 0;
protected:
virtual void foo(int i) = 0;
};
class Derived
: public boost::enable_shared_from_this<Derived>,
public Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
std::map<int, int> data;
public:
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
std::for_each(data.begin(), data.end(),
boost::bind(&Derived::foo, boost::enable_shared_from_this<Derived>::shared_from_this(),
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
std::set<Base_ptr> Bases_;
Base_ptr derived(new Derived());
Bases_.insert(derived);
derived->test();
return 0;
}
But I got an error at run-time :
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_weak_ptr> >'
what(): tr1::bad_weak_ptr
Might someone have a clue about how to manage that ?
Thanks.
Etienne.
It works with this workaround, but I'm not satisfied with it, so if someone find a better solution, go ahead.
#include <boost/bind.hpp>
#include <iostream>
#include <map>
#include <set>
#include <algorithm>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
class Base
: public boost::enable_shared_from_this<Base>,
private boost::noncopyable
{
public:
virtual void test() = 0;
//protected:
virtual void foo(int i) = 0;
};
class Derived
: public Base
{
protected:
void foo(int i)
{ std::cout << "Base: " << i << std::endl; }
std::map<int, int> data;
public:
Derived()
{
data[0] = 5;
data[1] = 6;
data[2] = 7;
}
void test()
{
std::for_each(data.begin(), data.end(),
boost::bind(&Base::foo, shared_from_this(),
boost::bind(&std::map<int, int>::value_type::second, _1)));
}
};
typedef boost::shared_ptr<Base> Base_ptr;
int main(int, const char**)
{
std::set<Base_ptr> Bases_;
Base_ptr derived(new Derived());
Bases_.insert(derived);
derived->test();
return 0;
}