I have simple class with multiple variable for the same type :
class Hello : public HelloPure
{
private :
int X;
int Y;
int Z;
I understand how overload work, but i can't find a way to make the following logic work :
mh->X/*Or GetX()*/ += somevalue;
mh->Y/*Or GetX()*/ += somevalue2;
mh->Z/*Or GetX()*/ += somevalue3;
I couldn't figure out how to reproduce a :
void operator +=(int &val, int val2);
That would not lead to a : "too many argument" error.
My main goal is to avoid the following :
mh->SetX(mh->GetX() + somevalue);
mh->SetY(mh->GetY() + somevalue2);
mh->SetZ(mh->GetZ() + somevalue3);
The reason is that my real environement is a lot more "heavy", and an overload may be more opptimise than the current solution.
Thanks you for future answer.
Edit/Update :
A good solution found user253751, but that doesn't work in my specific situation (i'll explain after) is to return a reference :
int &GetX();
and you canse us it :
a->GetX() += 5;
But in my situation i can't do that, i'm actually transfering information between c++ anb c#.
So i have a c++ Pure class pointer that i will use to compute my data, the pointer will be initialize with a CLI (c++/c#) class inheriting from my pure class, and the Cli pointer manage a pointer to my c# class.
When i do a GetX for exemple, it's more like that :
PurePointerClass->GetX()->will call the CLI class GetX() functiun
and in the GetX() { return m_PointerToManagedC#Object->GetX(); }
This make me unable to return directly a reference to my c# variable.
A common solution is to use one or more reference wrapper classes. Depending on how different your three cases really are, you may wish to use one wrapper with mutable data, or multiple wrappers:
class Hello {
void* m_PointerToManaged = nullptr;
public:
class XRef {
void* m_PointerToManaged;
public:
XRef(void* m_PointerToManaged) : m_PointerToManaged(m_PointerToManaged) { }
void operator+=(int) {
// your code
}
};
XRef GetX() { return {m_PointerToManaged}; }
class YRef {
void* m_PointerToManaged;
public:
YRef(void* m_PointerToManaged) : m_PointerToManaged(m_PointerToManaged) { }
void operator+=(int) {
// something else
}
};
YRef GetY() { return {m_PointerToManaged}; }
class ZRef {
void* m_PointerToManaged;
public:
ZRef(void* m_PointerToManaged) : m_PointerToManaged(m_PointerToManaged) { }
// maybe Zs cannot be added to?
//void operator+=(int) {
//}
};
ZRef GetZ() { return {m_PointerToManaged}; }
};
https://godbolt.org/z/8nW6c5
The resulting object still knows about the managed object (alternatively, you can also pass this and let it use common functionality of Hello), but it is now possible to specify addition operators for an object that is only responsible for one of the three different values.
Related
As per the documentation(https://isocpp.org/wiki/faq/objective-c#objective-c-and-inherit), which says:
The purpose of inheritance in C++ is to express interface compliance (subtyping), not to get code reuse. In C++, code reuse usually comes via composition rather than via inheritance. In other words, inheritance is mainly a specification technique rather than an implementation technique.
How to comprehend it? Could anybody make it clear by some simple examples?
Suppose you have a (admittedly silly) class named store_an_int:
class store_an_int {
public:
store_an_int(int x) : val(x) {}
void set_my_value(int x) { val = x; }
int get_my_value() const { return val; }
private:
int val;
};
Now you can store and retrieve an integer value:
store_an_int value(3);
std::cout << value.get_my_value(); // displays "3"
value.set_my_value(4);
std::cout << value.get_my_value(); // displays "4"
Now you have a class that needs to store an int and do some work on it. You could write it like this:
class doubler : public store_an_int {
public:
doubler(int x) : store_an_int(x) {}
int get_my_value() const { return store_an_int::get_my_value() * 2; }
};
Now you can store an integer value and retrieve its doubled value:
doubler value(3);
std::cout << value.get_my_value(); // displays "6"
value.set_my_value(4);
std::cout << value.get_my_value(); // displays "8"
That's code reuse. Yes, doubler stores an int value, but that's incidental to what it does, and using inheritance is misleading. doubler has two member functions which have the same names as the member functions in store_an_int. But what do you want to happen if someone adds a member function to store_an_int, let's say, void store_an_int::show() const { std::cout << val << '\n'; }? Now doubler has a new member function, show(), that shows the wrong value. Yes, you could rewrite doubler to store the doubled value instead of the raw value, and that would make store_an_int::show() show the right value. But if you don't want that function, you're still stuck with it.
Instead, the code should use composition:
class doubler {
public:
doubler(int x) : value(x) {}
int get_my_value() const { return value.get_my_value() * 2; }
void store_my_value(int x) { value.store_my_value(x); }
private:
store_my_value value;
};
Now if store_an_int adds a member function, it doesn't become part of the interface to doubler, and you can simply ignore it.
A property is a public data member of a class, which can be accessed by client code. And the owning object receives a notification (in the form of get/set notification callback) whenever the client code reads or modifies the property.
Some languages (like C#) have built-in properties.
I want to create a property for C++ that will be RAM-efficient.
The most obvious way to make a property is something like this:
class Super;
struct Prop {
Prop( Super * super ) : m_super(*super), m_a(0) {}
int operator=( int a );
operator int() const;
int m_a;
Super & m_super;
};
struct Super {
Super() : one(this), two(this) {}
void onSet() { printf("set"); }
void onGet() { printf("get"); }
Prop one;
Prop two;
};
int Prop::operator=( int a ) { m_super.onSet(); m_a = a; return a; }
Prop::operator int() const { m_super.onGet(); return m_a; }
Trouble is - every property has to keep a pointer to the outer class which I consider costly.
I want to know if there is a more RAM-efficient way to do this?
For example, if all Super-classes are generated, is it allowed by the Standard to get a pointer to the outer class from this pointer of the property?
Something like this:
struct Prop {
Prop( uint8_t offset ) : m_offset(offset), m_a(0) {}
int operator=( int a );
operator int() const;
int m_a;
const uint8_t m_offset;
};
int Prop::operator=( int a ) {
Super * super = (Super *)( ((char *)this) + m_offset);
super->onSet(); m_a = a; return a;
}
struct Super {
// assuming exact order of properties
Super() : one(0), two(sizeof(Prop)) {}
void onSet() { printf("set"); }
void onGet() { printf("get"); }
Prop one;
Prop two;
};
Since this offset is a constant expression it (theoretically) can be kept in ROM (or at least it can be smaller than sizeof(pointer)).
Or maybe there is another way?
c++ has properties as language extension
Look no further, msvc has support.
clang compiler also supports this syntax. Im not sure about gcc.
Storing offset can be also be done
Just, in the constructor calculate the offset from this, ala. :
Prop( Super& super ) {
uint8_t offset = this - std::addressof(super );//somewhat unmaintable - but may save some bytes
}
then when used, calculate back using this
Please note the space saving may be less than it seems due to alignment and padding.
I obviously don't know the context of your code, so this may be inconceivable in your specific implementation, but you could do something like
class Prop(){
Prop() : m_a(0){};
int operator=(int a){m_a = a;};
int m_a;
}
class Super(){
public:
int set_prop(int index, int value){
m_props[index] = value;
onSet();
return value;
}
private:
void onSet(){};
std::vector<Prop> m_props;
}
Obviously you need to initialize the vector and handle error cases etc but the logic is there - if you only access the props through the super.
That leaves you with purely the size of the sequence of structs with no pointers back to the super.
I have a bit of a design problem:
I have a class describing a Robot; It can move to different directions, move a camera to different views etc. It looks something like this:
class Robot {
private:
...
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
I want to add another method which performs a series of events. Thing is, I need able to abort the events midway.
I do want to clarify that the robot is running on a micro controller and not on a standard OS - so I can't really send a signal to the process or anything.
My first idea was to store the event functions in an array and iterate over it:
#typedef void(robo_event *)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
this->next_event = nullptr;
}
void perform_event_series() {
for(this->next_event = *event_sequence; this->next_event != nullptr; this->next_event+=sizeof(robo_event)) {
this->next_event();
}
}
void abort_event_series() {
this->next_event = nullptr;
}
Thing is, the c++ standard forbids storing addresses of member functions, so this is starting to get awkward. I can make the functions static, but I do need to use them quite frequently and that would still be awkward. I want to be able to change to event sequence without too much work if changes are yet to come, so I thought that saving those on some sort of array / vector would be the best.
Any help with c++ member function syntax / better ideas on how to approach this problem would be much appreciated.
Thing is, the c++ standard forbids storing addresses of member functions
C++ most certainly allows you to store pointers to member functions (and variables), but the syntax is a bit different to accommodate the this pointer type, virtual functions, inheritance, etc.
class Example
{
public:
double foo(int x) { return x * 1.5; }
};
int main() {
double (Example::* member_function_ptr)(int);
member_function_ptr = &Example::foo;
Example example;
std::cout << (example.*member_function_ptr)(2) << std::endl;
}
If all your functions are for the same class, same return type, same arguments, etc. then you can make a table of them easy enough.
Storing pointers to member functions is perfectly allowable in c++:
#include <vector>
class Robot {
private:
public:
void move_right();
void move_left();
void switch_camera();
void raise_camera();
};
struct Action
{
Action(void (Robot::*what)(void))
: what(what)
{}
void perform(Robot& who) const
{
(who.*what)();
}
void (Robot::*what)(void);
};
bool should_abort();
void perform_actions(Robot& who, std::vector<Action> const& actions)
{
for (auto&& action : actions)
{
if (should_abort()) break;
action.perform(who);
}
}
int main()
{
std::vector<Action> actions {
&Robot::move_right,
&Robot::raise_camera,
&Robot::switch_camera,
&Robot::move_left
};
Robot r;
perform_actions(r, actions);
}
Pointers to functions are of different types to pointers to members.
You need void(Robot::*)(void) not void(*)(void).
class Robot {
private:
typedef void(Robot::*robot_event)(void)
robo_event next_event;
robo_event *event_sequence;
Robot() {
next_event = nullptr;
}
void perform_event_series() {
for(next_event = *event_sequence; next_event != nullptr; ++next_event) {
(this->*next_event)();
}
}
void abort_event_series() {
next_event = nullptr;
}
public:
void move_right();
void move_left();
void switch_camera()
void raise_camera()
}
I have code like this:
class Human
{
protected:
int age;
std::string sex;
public:
virtual void speak() = 0;
};
class Child:public Human
{
public:
void speak(){std::cout << "I am Child\n";}
};
class Man:public Human
{
public:
void speak(){std::cout << "I am Man\n";}
};
class Woman:public Human
{
public:
void speak(){std::cout << "I am Woman\n";}
};
(don't know, std::shared_ptr<Human> maybe?) operator*(std::shared_ptr<Child> &b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man")
{
return (i want b to become std::shared_ptr<Man>)
}
if(b->getAge()>18 && b->getSex()=="Woman")
{
return (here I want b to become std::shared_ptr<Woman>);
}
return;
}
int main(){
auto x = std::make_shared<Child>;
x*19;
}
I know it seems odd, but it's the simplest case i can think of, without having to write down all code i'm struggling with rn. Could someone explain, what type should overload be and how to change shared_ptr type, knowing they derive from same parent?
Objects cannot change type. A Child object will always be a Child object. What you can do is create a new object with the properties you want and return that:
std::shared_ptr<Human> operator*(std::shared_ptr<Human> b, int x)
{
b->setAge(b->getAge()+x);
if(b->getAge()>18 && b->getSex()=="Man") {
return std::make_shared<Man>(b->getAge());
} else if(b->getAge()>18 && b->getSex()=="Woman") {
return std::make_shared<Woman>(b->getAge());
} else {
return b;
}
}
int main(){
std::shared_ptr<Human> x = std::make_shared<Child>;
x = x*19;
}
This doesn't seem like a good design though. A Human's status as a child or adult would be better represented as an attribute of the object or by a function that checks if age is greater than 18.
You cannot make the type T<Derived> inherit from T<Base> because C++ templates do not support covariance. To do so would be unsafe for certain types, such as mutable references to containers. (Imagine taking a reference to std::vector<Cat> as std::vector<Animal>& and pushing back a dog!)
(I would make this answer a comment, but I don't have comment abilities.)
Update:
You can write a non-template wrapper that handles heap data:
class Wrapper
{
public:
Wrapper(Base* b) : raw(b) {}
~Wrapper() { delete raw; }
Base& get() { return *base; }
private:
Base* raw;
}
Of course, in your example, you use std::shared_ptr and not std::unique_ptr. You would have to handle reference counting instead of simply deleting the data in the destructor, but the technique of keeping an internal raw pointer still stands.
Update 2:
The above code could be used as is to provide a level of indirection, such that all classes that inherit from the base class may be held in the same type, without writing your own reference counter:
std::shared_ptr<Wrapper>
This solution may be seen as similar to doing std::shared_ptr<Base*>, except that the latter solution would leak memory.
I need to bind a method into a function-callback, except this snippet is not legal as discussed in demote-boostfunction-to-a-plain-function-pointer.
What's the simplest way to get this behavior?
struct C {
void m(int x) {
(void) x;
_asm int 3;
}};
typedef void (*cb_t)(int);
int main() {
C c;
boost::function<void (int x)> cb = boost::bind(&C::m, &c, _1);
cb_t raw_cb = *cb.target<cb_t>(); //null dereference
raw_cb(1);
return 0;
}
You can make your own class to do the same thing as the boost bind function. All the class has to do is accept the function type and a pointer to the object that contains the function. For example, this is a void return and void param delegate:
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
Usage:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
Now, since VoidDelegate<C> is a type, having a collection of these might not be practical, because what if the list was to contain functions of class B too? It couldn't.
This is where polymorphism comes into play. You can create an interface IDelegate, which has a function Invoke:
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
If VoidDelegate<T> implements IDelegate you could have a collection of IDelegates and therefore have callbacks to methods in different class types.
Either you can shove that bound parameter into a global variable and create a static function that can pick up the value and call the function on it, or you're going to have to generate per-instance functions on the fly - this will involve some kind of on the fly code-gen to generate a stub function on the heap that has a static local variable set to the value you want, and then calls the function on it.
The first way is simple and easy to understand, but not at all thread-safe or reentrant. The second version is messy and difficult, but thread-safe and reentrant if done right.
Edit: I just found out that ATL uses the code generation technique to do exactly this - they generate thunks on the fly that set up the this pointer and other data and then jump to the call back function. Here's a CodeProject article that explains how that works and might give you an idea of how to do it yourself. Particularly look at the last sample (Program 77).
Note that since the article was written DEP has come into existance and you'll need to use VirtualAlloc with PAGE_EXECUTE_READWRITE to get a chunk of memory where you can allocate your thunks and execute them.
#include <iostream>
typedef void(*callback_t)(int);
template< typename Class, void (Class::*Method_Pointer)(void) >
void wrapper( int class_pointer )
{
Class * const self = (Class*)(void*)class_pointer;
(self->*Method_Pointer)();
}
class A
{
public:
int m_i;
void callback( )
{ std::cout << "callback: " << m_i << std::endl; }
};
int main()
{
A a = { 10 };
callback_t cb = &wrapper<A,&A::callback>;
cb( (int)(void*)&a);
}
i have it working right now by turning C into a singleton, factoring C::m into C::m_Impl, and declaring static C::m(int) which forwards to the singleton instance. talk about a hack.