I am trying to initialize objects from other classes in my constructor as shared pointers. I need a shred pointer because I need a reference to use in another method in ...
header
class MyClass
{
public:
MyClass() ;
~MyClass() {};
void myMethod();
private:
std::shared_ptr<dds::pub::Publisher>m_pub;
std::shared_ptr<dds::domain::DomainParticipant>m_part;
};
cpp
MyClass::MyClass()
{
m_part = std::make_shared<dds::domain::DomainParticipant>(domain::default_id());
m_pub = std::make_shared<dds::pub::Publisher>(m_part);
}
MyClass::myMethod()
{
//m_part, m_pub are used here
}
what am I missing here?
Error C2039 'delegate': is not a member of 'std::shared_ptr<dds::domain::DomainParticipant>'
dds::pub::Publisher
namespace dds
{
namespace pub
{
typedef dds::pub::detail::Publisher Publisher;
}
}
Publisher
namespace dds { namespace pub { namespace detail {
typedef
dds::pub::TPublisher<org::eclipse::cyclonedds::pub::PublisherDelegate> Publisher;
} } }
PublisherDelegate
namespace dds { namespace pub { namespace detail {
typedef
dds::pub::TPublisher<org::eclipse::cyclonedds::pub::PublisherDelegate> Publisher;
} } }
class OMG_DDS_API PublisherDelegate : public
org::eclipse::cyclonedds::core::EntityDelegate
{
public:
typedef ::dds::core::smart_ptr_traits< PublisherDelegate >::ref_type ref_type;
typedef ::dds::core::smart_ptr_traits< PublisherDelegate >::weak_ref_type weak_ref_type;
PublisherDelegate(const dds::domain::DomainParticipant& dp,
const dds::pub::qos::PublisherQos& qos,
dds::pub::PublisherListener* listener,
const dds::core::status::StatusMask& event_mask);
TPublisher
template <typename DELEGATE>
class dds::pub::TPublisher : public dds::core::TEntity<DELEGATE>
{
public:
typedef dds::pub::PublisherListener Listener;
public:
OMG_DDS_REF_TYPE_PROTECTED_DC(TPublisher, dds::core::TEntity, DELEGATE)
OMG_DDS_IMPLICIT_REF_BASE(TPublisher)
TPublisher(const dds::domain::DomainParticipant& dp);
TPublisher(const dds::domain::DomainParticipant& dp,
const dds::pub::qos::PublisherQos& qos,
dds::pub::PublisherListener* listener = NULL,
const dds::core::status::StatusMask& mask = dds::core::status::StatusMask::none());
I tried the method given in answer got new error,
Error C2672 'std::dynamic_pointer_cast': no matching overloaded function in TPublisher.hpp
I guess m_pub should be initialised like this
m_pub = std::make_shared<dds::pub::Publisher>(*m_part);
The class dds::pub::Publisher a.k.a. dds::pub::TPublisher has the constructor taking const dds::domain::DomainParticipant by reference.
The answer is changed after the question has been updated.
Related
I try to implement Scott Mayer book code example, the example is about calling functor through function object
the header file gameCharachter.h
#ifndef GAMECHARACTER_H
#define GAMECHARACTER_H
#include <iostream>
#include <typeinfo>
using namespace std;
#include <tr1/functional>
class GameCharacter;
int defaultHealthCalc(const GameCharacter& gc);
class GameCharacter
{
public:
typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc;
explicit GameCharacter(HealthCalcFunc hcf = defaultHealthCalc)
: healthFunc(hcf)
{
}
~GameCharacter()
{
}
int healthValue() const
{
return healthFunc(*this);
}
private:
HealthCalcFunc healthFunc;
};
class EyeCandyCharacter: public GameCharacter // another character
{
public:
explicit EyeCandyCharacter(HealthCalcFunc hcf = defaultHealthCalc)
: GameCharacter(hcf)
{
cout<<typeid(*this).name()<<"::"<<__FUNCTION__<<""<<endl;
}
};
struct HealthCalculator
{
/*explicit*/ HealthCalculator()
{
}
int operator()(const GameCharacter& gc) const // calculation function
{
cout<<typeid(*this).name()<<"::"<<__FUNCTION__<<""<<endl;
return 0;
}
};
#endif // GAMECHARACTER_H
the main.cpp is :
#include "gamecharacter.h"
int main()
{
EyeCandyCharacter ecc1(HealthCalculator());
ecc1.healthValue();
}
why function<> object refuse to call the operator() function in healthvalue()
EyeCandyCharacter ecc1(HealthCalculator());
declares a function called ecc1 that takes an argument of type "pointer to function taking no arguments and returning a HealthCalculator" and returns a EyeCandyCharacter. I assume that this isn't your intent.
this is the correct call , it should be called by bind
#include "gamecharacter.h"
int main()
{
HealthCalculator hc;
EyeCandyCharacter ecc1(std::tr1::bind(&HealthCalculator::operator(),hc,tr1::placeholders::_1));
ecc1.healthValue();
}
I'm trying to implement a C++ factory class that also perform the self registration of some derived classes. My implementation is based on the library:
http://arcticinteractive.com/2008/10/06/boost-centric-factory-pattern-implementation/
that is based on the Boost library. Just to give you a quick overview of this library, here is a simple self-explained (I hope) example:
struct foo { virtual ~foo() {} };
struct bar : foo { bar(int i) { std::cout << "bar() " << i << "\n"; } };
struct baz : foo { baz(int i) { std::cout << "baz() " << i << "\n"; } };
...
typedef factory< foo*(int) > myfactory_t;
myfactory_t f;
// Register a default (operator new) creator function
// for an implementation type
register_new_ptr<bar>(f, "bar");
register_new_ptr<baz>(f, "baz");
// Create objects through the factory
foo* fooimpl1 = f["bar"](1234);
foo* fooimpl2 = f["baz"](4321);
What I'm trying to do is to delegate each class to self-register them self to the factory using a static method. Here is the code:
animal.h
#pragma once
#include <cstring>
#include <iostream>
#include "factory.hpp"
#include "abstract_factory.hpp"
class zoo;
using namespace std;
using namespace boost::factory;
class animal{
virtual const std::string do_sound() const = 0;
std::string name_;
int age_;
zoo* myZoo_;
public:
animal(const std::string& name, int age, zoo* myZoo) : name_(name), age_(age), myZoo_(myZoo)
{}
virtual ~animal() {}
const std::string sound() const
{
return do_sound();
}
const std::string& name() const { return name_; }
const int age() const { return age_; }
};
template <class T>
struct animalFactory{
typedef factory< animal*(std::string&, int, zoo*) > myfactory_t;
static const myfactory_t* f;
static bool registerAnimal(const std::string& animalname){
return register_new_ptr<T>(&f, animalname);
};
};
When I try to register a class like:
crocodile.cpp
#include "crocodile.h"
bool r = animalFactory<crocodile>::registerAnimal("crocodile");
I get an error from visual studio 2012 that is:
animal.h(41): error C2893: Failed to specialize function template 'bool boost::factory::register_new_ptr(Factory &,Factory::id_param_type)'
Could someone help me to understand what is going on here? Thanks a lot!
I already asked about my Problem, now I'm on the next Step. In the code below I have the Problem, that I always have to make the EventHandler (Server::HandleMessage) static. But I need to have it non static to access other Variables in the Server class from within the Handler.
How can I achieve this?
Here my Code:
#include <iostream>
#include <functional>
using namespace std;
class Client{
public:
struct MessageReceiveArgs {
MessageReceiveArgs(int ID, const std::string& Text) : ID(ID), Text(Text) {}
int ID;
std::string Text;
};
std::function<void(MessageReceiveArgs)> onMessageReceive;
Client(){}
void FireEvent(){
this->onMessageReceive(MessageReceiveArgs(16, "SomeText"));
}
};
class Server{
public:
int i;
Server(){
this->client.onMessageReceive = &Server::HandleMessage;
this->i = 5;
}
void FireEvent(){
this->client.FireEvent();
}
Client client;
static void HandleMessage(Client::MessageReceiveArgs args) {
std::cout<<"ID "<<args.ID<<": "<<" "<<args.Text<<std::endl;
//need it non static
//std::cout<<"I: "<<this->i<<std::endl;
}
};
int main() {
Server sv = Server();
sv.FireEvent();
}
As mentioned in my earlier Post, i'm new to Standard C++ (Unix).
I'm fairly sure this is what you're after. You need to bind the implicit this explicitly when invoking a pointer-to-member through std::function in the fashion you seem to desire.
#include <iostream>
#include <functional>
using namespace std;
class Client{
public:
struct MessageReceiveArgs
{
MessageReceiveArgs(int ID, const std::string& Text)
: ID(ID), Text(Text) {}
int ID;
std::string Text;
};
Client(){}
void FireEvent()
{
this->onMessageReceive(MessageReceiveArgs(16, "SomeText"));
}
std::function<void(MessageReceiveArgs)> onMessageReceive;
};
class Server
{
public:
int i;
Server()
{
this->client.onMessageReceive
= std::bind(&Server::HandleMessage, this, std::placeholders::_1);
this->i = 5;
}
void FireEvent()
{
this->client.FireEvent();
}
Client client;
void HandleMessage(Client::MessageReceiveArgs args)
{
std::cout<<"ID "<<args.ID<<": "<<" "<<args.Text<<std::endl;
}
};
int main()
{
Server sv = Server();
sv.FireEvent();
}
Output
ID 16: SomeText
I've got problems passing a member function of a C++ CLI class to a native C callback from a library.
To be precise its the Teamspeak 3 SDK.
You can pass a non member function using the following code without problem:
struct ClientUIFunctions funcs;
/* Initialize all callbacks with NULL */
memset(&funcs, 0, sizeof(struct ClientUIFunctions));
funcs.onConnectStatusChangeEvent = onConnectStatusChangeEvent;
But I need to pass a pointer to a member function, for example:
funcs.onConnectStatusChangeEvent = &MyClass::onConnectStatusChangeEvent;
Any other idea how to use the event within a non static member function is welcome to.
Thanks in advance!
This can only be done via a static class function because C doesn't know anything about the vtable or what object the function is part of. See below for a C++ and Managed C++ example
This could however be a work around, build a wrapper class which handles all the callbacks you need.
#include <string.h>
struct ClientUIFunctions
{
void (*onConnectStatusChangeEvent)(void);
};
class CCallback
{
public:
CCallback()
{
struct ClientUIFunctions funcs;
// register callbacks
my_instance = this;
/* Initialize all callbacks with NULL */
memset(&funcs, 0, sizeof(struct ClientUIFunctions));
funcs.onConnectStatusChangeEvent = sOnConnectStatusChangeEvent;
}
~CCallback()
{
// unregister callbacks
my_instance = NULL;
}
static void sOnConnectStatusChangeEvent(void)
{
if (my_instance)
my_instance->OnConnectStatusChangeEvent();
}
private:
static CCallback *my_instance;
void OnConnectStatusChangeEvent(void)
{
// real callback handler in the object
}
};
CCallback *CCallback::my_instance = NULL;
int main(int argc, char **argv)
{
CCallback *obj = new CCallback();
while (1)
{
// do other stuff
}
return 0;
}
Another possibility would be if the callback supports and void *args like void (*onConnectStatusChangeEvent)(void *args); which you can set from the plugin. You could set the object in this args space so in de sOnConnectStatusChangeEvent you would have something like this:
static void sOnConnectStatusChangeEvent(void *args)
{
if (args)
args->OnConnectStatusChangeEvent();
}
For managed C++ it should be something like this, however I can't get it to compile because it doesn't like the template brackets..
wrapper.h:
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Text;
namespace Test
{
struct ClientUIFunctions
{
void (*onConnectStatusChangeEvent)(void);
};
public delegate void ConnectStatusChangeEvent(void);
public ref class ManagedObject
{
public:
// constructors
ManagedObject();
// destructor
~ManagedObject();
//finalizer
!ManagedObject();
event ConnectStatusChangeEvent^ OnConnectStatusChangeEvent {
void add(ConnectStatusChangeEvent^ callback) {
m_connectStatusChanged = static_cast<ConnectStatusChangeEvent^> (Delegate::Combine(m_connectStatusChanged, callback));
}
void remove(ConnectStatusChangeEvent^ callback) {
m_connectStatusChanged = static_cast<ConnectStatusChangeEvent^> (Delegate::Remove(m_connectStatusChanged, callback));
}
void raise(void) {
if (m_connectStatusChanged != nullptr) {
m_connectStatusChanged->Invoke();
}
}
}
private:
ConnectStatusChangeEvent^ m_connectStatusChanged;
};
class CCallback
{
public:
static void Initialize(ManagedObject^ obj);
static void DeInitialize(void);
private:
static void sOnConnectStatusChangeEvent(void);
static gcroot<ManagedObject^> m_objManagedObject;
};
}
wrapper.cpp:
#include <string.h>
#include "wrapper.h"
using namespace System;
using namespace Test;
void CCallback::Initialize(ManagedObject^ obj)
{
struct ClientUIFunctions funcs;
// register callbacks
m_objManagedObject = obj;
/* Initialize all callbacks with NULL */
memset(&funcs, 0, sizeof(struct ClientUIFunctions));
funcs.onConnectStatusChangeEvent = sOnConnectStatusChangeEvent;
}
void CCallback::DeInitialize(void)
{
// unregister callbacks
m_objManagedObject = nullptr;
}
void CCallback::sOnConnectStatusChangeEvent(void)
{
if (m_objManagedObject != nullptr)
m_objManagedObject->OnConnectStatusChangeEvent();
}
// constructors
ManagedObject::ManagedObject()
{
// you can't place the constructor in the header but just for the idea..
// create wrapper
CCallback::Initialize(this);
}
// destructor
ManagedObject::~ManagedObject()
{
this->!ManagedObject();
}
//finalizer
ManagedObject::!ManagedObject()
{
CCallback::DeInitialize();
}
gcroot<ManagedObject^> CCallback::m_objManagedObject = nullptr;
int main(array<System::String ^> ^args)
{
ManagedObject^ bla = gcnew ManagedObject();
while (1)
{
// do stuff
}
return 0;
}
I have made a map of functions. all these functions are void and receive single string parameter.
code:
void f1(string params){...}
void f2(string params){...}
void f3(string params){...}
map<string , void*> funcMap;
funcMap["f1"] =(void*)&f1;
funcMap["f2"] =(void*)&f2;
funcMap["f3"] =(void*)&f3;
how do i call a function?
I tried the next code, but id doesn't work:
void (*func)(string) = &funcMap[commandType];
func(commandParam);
I get this error message:
Server.cpp:160:46: error: cannot convert ‘void**’ to ‘void (*)(std::string) {aka void (*)(std::basic_string<char>)}’ in initialization
using pfunc = void (*)(string);
map<string, pfunc> funcMap;
funcMap["f1"] = f1; //and so forth
And then call:
pfunc f = funcMap[commandType];
(*f)(commandParam);
In general, why throw away type safety? If it's a map of function pointers, declare it to be one.
Why not just have those as separate classes.
Then have the methods as virtual.
You can then have a map between the string and the base class.
i.e.
class Someoperation
{
virtual void Doit() = 0;
};
map<string, Someopertion> ops;
Then
class MyOp : public Someoperation
{
void Doit() { /* Some code here */}
};
Just add objects
ops["Hello"] = MyOp();
then call it
ops["Hello"].Doit();
&funcMap[commandType]
Just drop the &. Your compile error was useful here. It had a void** on the right which is because you took the address of a function pointer. You don't want two levels of indirection there.
Try C++ style. It has overhead for allocation and inheritance, but it's more flexible and extensible if you'll need some more functionality in the future.
#include <iostream>
#include <string>
#include <unordered_map>
#include <memory>
using namespace std;
class Someoperation {
public:
virtual void Doit() = 0;
};
class MyOp1 : public Someoperation {
public:
void Doit() final { cout << "MyOp1" << endl; }
};
class MyOp2 : public Someoperation {
public:
void Doit() final { cout << "MyOp2" << endl; }
};
int main() {
unordered_map<string, unique_ptr<Someoperation> > ops;
ops["1"] = unique_ptr<Someoperation>(new MyOp1);
ops["2"] = unique_ptr<Someoperation>(new MyOp2);
ops["1"]->Doit(); // Out: MyOp1
ops["2"]->Doit(); // Out: MyOp2
return 0;
}