class IEngine: public ICoreObject
{
private:
Network *_Network;
bool _Process;
public:
IEngine();
~IEngine();
void Initial(...);
void StartServer(unsigned short port);
bool Process();
void StopProcess();
void StartProcess();
friend void ShellCode(int id,struct NE_Bin var);
};
Why i cant use _Network from ShellCode ?
this is definition of ShellCode function
void ShellCode(int id,struct NE_Bin var) //функция-друг
{
std::cout<<"ShellFunc Delegated"<<std::endl;
var.data = (void *)"T";
var.length = 1;
//_Network->SendMessageW(id, var);
}
Im trying to get to the _Network class and i get errors.
IEngine has ShellCode as a friend. That means you can access private **members of an IEngine object. _Network is just a variable in your context, not bound to anything.
Something like this would work:
void ShellCode(int id,struct NE_Bin var, IEngine* pEngine)
{
std::cout<<"ShellFunc Delegated"<<std::endl;
var.data = (void *)"T";
var.length = 1;
pEngine->_Network->SendMessageW(id, var);
}
but you need to pass the IEngine as parameter:
IEngine* pEngine /*initialize it here*/;
ShellCode(0, NE_Bin(), pEngine);
or you can use a global instance inside the method (if you have one).
Well you'd need an instance of of IEngine as a parameter to access it's member variable...
Related
I am about to write a custom ESPHome component. I don't have much experience with C language and I am facing some troubles using external library.
For demonstration, I prepared a simple component class..
class Test: public Component {
public:
auto t = timer_create_default();
void setup() override {
ESP_LOGD("TEST", "Test setup called!");
t.every(1000, TestLog);
}
void loop() override {
ESP_LOGD("TEST", "Test loop called!");
t.tick();
}
bool TestLog(void *) {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
}
With this, I receive:
In file included from src\main.cpp:32:0: src\Test.h:7:35: error:
non-static data member declared 'auto'
auto t = timer_create_default();
I took it from some example where they did not have the class, but I can't find out, how to use it.
The library is:
https://github.com/contrem/arduino-timer/
I can still rewrite it without this timer completely and handle it only in the loop function, but I would like to understand what I am doing wrong.
If I change the return type to Timer<> I got another error:
src\Test.h: In member function 'virtual void Test::setup()':
src\Test.h:11:24: error: no matching function for call to
'Timer<>::every(int, )'
t.every(1000, TestLog);
You can not use auto to declare non-static member variables so you need to replace auto with the type returned by timer_create_default().
If you are not sure what type it returns, you can simply use decltype in the declaration:
decltype(timer_create_default()) t = timer_create_default();
If I read the code in the repo correctly, the returned type is Timer<>, so this should also work:
Timer<> t = timer_create_default();
or simply:
Timer<> t;
Also: The function pointer passed to t.every() should be a bool (*)(void*) but TestLog is a non-static member function and the pointer type is bool (Test::*)(void*) - You can fix that by making TestLog static:
class Test: public Component {
public:
// ...
static bool TestLog(void *) {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
};
If you want to get the Test instance in the TestLog callback, make the Timer
Timer<TIMER_MAX_TASKS, millis, Test*> t;
and change TestLog:
class Test: public Component {
public:
// ...
static bool TestLog(Test* t) {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
};
and in setup():
t.every(1000, TestLog, this);
You'll now get a pointer to the Test instance in the TestLog callback and you can use this to call a non-static member function in Test.
Full example:
class Test : public Component {
public:
Timer<TIMER_MAX_TASKS, millis, Test*> t;
void setup() override {
ESP_LOGD("TEST", "Test setup called!");
// call the static member function every second:
t.every(1000, TestLogProxy, this);
}
void loop() override {
ESP_LOGD("TEST", "Test loop called!");
t.tick();
}
bool TestLog() {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
static bool TestLogProxy(Test* t) {
// forward the callback call to the non-static member function:
return t->TestLog();
}
};
I am using C++ 14 with clang on MacOS Sierra. I want to enforce a rule by design. Following is the rule.
I have a member variable in my class say:
unsigned int m_important_num;
There are 4 methods in my class.
fun1();
fun2();
fun3();
fun4();
Objective:
I want only fun2() to be able to change the value of m_important_num.
Question:
Is it possible to make it compiler error if any method other than fun2() changes the variable?
One possible way is to declare it const somehow empower fun2() to change const variables? Is this a good solution? Or are their any better solutions?
Secondary question:
Is it a wrong design to try do such a thing?
Sort of, with additional layer:
class S1 {
public:
void fun2() { /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
unsigned int m_important_num;
};
class S2 : private S1
{
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
As Yakk commented, if func2 need access to S2 members, CRTP can solve that:
template <typename Derived>
class S1 {
public:
void fun2() { asDerived().foo3(); /*Modify m_important_num */ }
unsigned int getImportantNum() const { return m_important_num;}
private:
Derived& asDerived() { return stataic_cast<Derived&>(*this); }
private:
unsigned int m_important_num;
};
class S2 : private S1<S2>
{
// friend class S1<S2>; // If required.
public:
void fun1();
using S1::fun2; // or void fun2() {S1::fun2();}
void fun3();
void fun4();
};
Encapsulate it down. Put m_important_num in its own class. Aggregate it in your existing class. Have a getter for it. Then put fun2() as a member function of your inner class.
I little variant (if I understand correctly) of the Jeffrey solution: put the variable in an inner class and make it private; create a public getter and make func2() friend to the inner class.
I mean
struct foo
{
int f1 () { return b0.getVal(); }; // you can read `val` everywhere
void f2 () { b0.val = 42; }; // you can write `val` in f2()
void f3 () { /* b0.val = 42; ERROR ! */ }; // but only in f2()
class bar
{
private:
int val = 24;
public:
int getVal () { return val; }
friend void foo::f2 ();
};
bar b0;
};
In other words: friend is your friend.
If you want to prevent a method from modifying any member in the class you can use the trailing const identifier:
class something{
private:
unsigned int var;
public:
void fun1() const;
void fun2();
void fun3() const;
void fun4() const;
}
Here, only fun2() will be able to modify the variable.
I know there are lots of good answers, but there is also an option that you sort of alluded to in your question:
One possible way is to declare it const somehow empower fun2() to change const variables?
#include <iostream>
using uint = unsigned int;
class Test
{
const uint num;
public:
Test(uint _num)
:
num(_num)
{}
uint get_num() const
{
return num;
}
void can_change_num(uint _new_num)
{
uint& n(const_cast<uint&>(num));
n = _new_num;
}
void cant_change_num(uint _new_num)
{
// num = _new_num; // Doesn't compile
}
};
int main()
{
Test t(1);
std::cout << "Num is " << t.get_num() << "\n";
t.can_change_num(10);
std::cout << "Num is " << t.get_num() << "\n";
return 0;
}
Produces
Num is 1
Num is 10
You already got lots of good answers to your primary question. I'll try to address the secondary one.
Is it a wrong design to try do such a thing?
It's hard to say w/o knowing more about your design. In general anything like this detected during a code review would raise a big red flag. Such a protection makes sense in a case of a big class with convoluted logic/implementation. Otherwise why would you like to go an extra mile and make your code much more complicated? The fact you seek for this can indicate your class became unmanageable.
I'd recommend to consider splitting it to smaller parts with better defined logic where you won't worry such mistakes can happen easily.
I want to do something like this:
struct CLI_Command{
CLI_Command(char* s, void (*h)(void)){
command_string = s;
handler = h;
}
char* command_string;
void (*handler)(void);
};
class CLI {
public:
CLI();
private:
CLI_Command cli_table[NO_CLI_COMMANDS] = {
CLI_Command("Command1", handler1),
CLI_Command("Command2", handler2)
};
void handler1(){};
void handler2(){};
};
I know that I need something similar to CLI::*handler, but I can't get the syntax right. I keep running into errors like this:
"error: no matching function for call to 'CLI_Command::CLI_Command(const char [4], <unresolved overloaded function type>)"
This illustrates the correct syntax:
class CLI;
struct CLI_Command
{
CLI_Command(char* s, void (CLI::*h)(void))
{
command_string = s;
handler = h;
}
char* command_string;
void (CLI::*handler)(void);
void raise( CLI* the_cli ) { return (the_cli->*handler)(); }
};
class CLI
{
public:
CLI();
private:
static CLI_Command cli_table[NO_CLI_COMMANDS];
void handler1(){};
void handler2(){};
};
CLI::CLI_Command cli_table[NO_CLI_COMMANDS] = {
{ "Command1", &CLI::handler1 },
{ "Command2", &CLI::handler2 }
};
Names of member functions do not decay to pointer-to-member. You must use & explicitly, and a qualified name, when creating a pointer-to-member.
In addition to other answers, another option is to use std::function together with std::bind():
struct CLI_Command{
...
std::function<void> handler;
};
class CLI {
...
CLI_Command cli_table[NO_CLI_COMMANDS] = {
{ "Command1", std::bind(&CLI::handler1, this) },
{ "Command2", std::bind(&CLI::handler2, this) }
};
void handler1(){};
void handler2(){};
};
void handler1(){}
void handler2(){}
are member functions of CLI. The correct way to "address to" them is &CLI::handler1 and not handler1. However then, they won't be accepted by void (*h)(void), which would need to be changed to void (CLI::*h)(void). But that is probably not what you want.
Maybe consider reading about std::function for type erasure, or make your handler1/handler2 static.
You should use the syntax for a pointer to class member instead of the syntax for a loose function pointer.
class CLI;
struct CLI_Command{
CLI_Command(char* s, void (CLI::*h)(void)){
command_string = s;
handler = h;
}
char* command_string;
void (CLI::*handler)(void);
};
In addition, make sure you call the function through the pointer of the current CLI class;
void CLI::process(char *cmd) {
CLI_Command command* = /* lookup the command */
this->(command->handle)();
}
To get it working, make your methods static
static void handler1(){};
static void handler2(){};
Whatever consequences (read here please, for more detailed info) this will have :-( .
I have to make some kind of bridge between two pieces of software, but am facing an issue I don't know how to deal with. Hopefully someone will have interesting and (preferably) working suggestions.
Here is the background : I have a C++ software suite. I have to replace some function within a given class with another function, which is ok. The problem is that the new function calls another function which has to be static, but has to deal with members of the class. This is this second function which is making me mad.
If the function is not static I get the following error :
error: argument of type ‘void (MyClass::)(…)’ does not match ‘void (*)(…)’
If I set it to static I get either the following error :
error: cannot call member function ‘void
MyClass::MyFunction(const double *)’ without object
or
error: ‘this’ is unavailable for static member functions
depending on if I use or not the "this" keyword ("Function()" or "this->Function()").
And finally, the class object requires some arguments which I cannot pass to the static function (I cannot modify the static function prototype), which prevents me to create a new instance within the static function itself.
How would you deal with such a case with minimal rewriting ?
Edit : Ok, here is a simplified sample on what I have to do, hoping it is clear and correct :
// This function is called by another class on an instance of MyClass
MyClass::BigFunction()
{
…
// Call of a function from an external piece of code,
// which prototype I cannot change
XFunction(fcn, some more args);
…
}
// This function has to be static and I cannot change its prototype,
// for it to be passed to XFunction. XFunction makes iterations on it
// changing parameters (likelihood maximization) which do not appear
// on this sample
void MyClass::fcn(some args, typeN& result)
{
// doesn't work because fcn is static
result = SomeComputation();
// doesn't work, for the same reason
result = this->SomeComputation();
// doesn't work either, because MyClass has many parameters
// which have to be set
MyClass *tmp = new MyClass();
result = tmp->SomeComputation();
}
Pointers to non-static member functions are a bit tricky to deal with. The simplest workaround would just be to add an opaque pointer argument to your function which you can then cast as a pointer to 'this', then do what you need with it.
Here's a very simple example:
void doSomething(int (*callback)(void *usrPtr), void *usrPtr)
{
// Do stuff...
int value = callback(usrPtr);
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(myCallback, this);
}
private:
int value_;
static int myCallback(void *usrPtr)
{
MyClass *parent = static_cast<MyClass *>(usrPtr);
return parent->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
In this example myCallback() can access the private value_ through the opaque pointer.
If you want a more C++-like approach you could look into using Boost.Function and Boost.Bind which allow you to pass non-static member functions as callbacks:
void doSomething(boost::function<int ()> callback)
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(boost::bind(&MyClass::myCallback, this));
}
private:
int value_;
int myCallback()
{
return value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
If you really can't change the function prototype you could use a global pointer, but that opens up all sorts of issues if you will ever have more than one instance of your class. It's just generally bad practice.
class MyClass;
static MyClass *myClass;
void doSomething(int (*callback)())
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
myClass = this;
doSomething(myCallback);
}
private:
int value_;
static int myCallback()
{
return myClass->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
Following spencercw's suggestion below the initial question I tried the "static member variable that you set to point to this" solution (the global variable would have been tricky and dangerous within the context of the software suite).
Actually I figured out there was already something like this implemented in the code (which I didn't write) :
static void* currentObject;
So I just used it, as
((MyClass*)currentObject)->SomeComputation();
It does work, thanks !!!
non-reentrant and non-thread-safe way is to pass "this" address using global variable.
You can move the result = SomeComputation(); out of your static function and place it in BigFunction right before your call to the static function.
How to Define or Implement C# Property in ISO C++ ?
Assume following C# code :
int _id;
int ID
{
get { return _id; }
set { _id = value; }
}
I know C# convert the get and set lines to getXXX and setXXX methods in compile time. in C++ , programmers usually define these two function manually like :
int _id;
int getID() { return _id; }
void setID(int newID) { _id = newID; }
but, I want to have the C# syntax or a stuff like it in order to have a simple usability.
In C#, we can use properties like :
ID = 10; // calling set function
int CurrentID = ID; // calling get function
In C++, we can use our function like :
setID(10); // calling set function
int CurrentID = getID(); // calling get function
Now tell me how can I implement the C# properties in ISO C++.
thanks.
As Alexandre C. has already stated, it's very awkward and not really worth it, but to give an example of how you might do it.
template <typename TClass, typename TProperty>
class Property
{
private:
void (TClass::*m_fp_set)(TProperty value);
TProperty (TClass::*m_fp_get)();
TClass * m_class;
inline TProperty Get(void)
{
return (m_class->*m_fp_get)();
}
inline void Set(TProperty value)
{
(m_class->*m_fp_set)(value);
}
public:
Property()
{
m_class = NULL;
m_fp_set = NULL;
m_fp_set = NULL;
}
void Init(TClass* p_class, TProperty (TClass::*p_fp_get)(void), void (TClass::*p_fp_set)(TProperty))
{
m_class = p_class;
m_fp_set = p_fp_set;
m_fp_get = p_fp_get;
}
inline operator TProperty(void)
{
return this->Get();
}
inline TProperty operator=(TProperty value)
{
this->Set(value);
}
};
In your class where you wish to use it, you create a new field for the property, and you must call Init to pass your get/set methods to the property. (pref in .ctor).
class MyClass {
private:
int _id;
int getID() { return _id; }
void setID(int newID) { _id = newID; }
public:
Property<MyClass, int> Id;
MyClass() {
Id.Init(this, &MyClass::getID, &MyClass::setID);
}
};
Short answer: you can't.
Long answer: You could try to simulate them via proxy classes, but believe me this is not worth the minor incovenience in having set/get functions.
You'd have basically to define a class which forwards all the behavior of the variable. This is insanely hard to get right, and impossible to be made generic.
Quite simply. I'd argue this even has no overhead compared to making the variable public. However, you can't modify this any further. Unless, of course, you add two more template parameters that are call backs to functions to call when getting and setting.
template<typename TNDataType>
class CProperty
{
public:
typedef TNDataType TDDataType;
private:
TDDataType m_Value;
public:
inline TDDataType& operator=(const TDDataType& Value)
{
m_Value = Value;
return *this;
}
inline operator TDDataType&()
{
return m_Value;
}
};
EDIT: Don't make the call back functions template parameters, just data members that are constant and must be initialized in the constructor for the property. This inherently has greater overhead than simply writing a get and set method your self, because you're making function calls inside of your gets and sets this way. The callbacks will be set at run-time, not compile-time.