I want to do something similar to Python's __getattribute()__
, but in C . It feels like I should be using some kind of pointer-to-member, but I can't really figure out how to get started.
The gist of what I want to do is define a class that contains pointers to other instances of the same class, as well as various data members. Then I want a method that can be called to do a specific operation, using a specific data member.
For example, if the class is like this:
class C{
public:
C* linked1;
C* linked2;
double d1;
double d2;
C(double d1, double d2) : d1{d1}, d2{d2} {};
double add(<pointer to member or something?>){
return linked1-><attribute> linked2-><attribute> <attribute>
}
};
I want to be able to call the method add()
like this:
C c1{1., 2.};
C c2{3., 4.};
C c3{5., 6.};
c1.linked1 = &c2;
c1.linked2 = &c3;
double a1 = c1.add(<use d1>); // a1 = 1. 3. 5.
double a2 = c1.add(<use d2>); // a2 = 2. 4. 6.
In Python, I would do this with __getattribute__()
like this:
class C:
def __init__(d1, d2):
self.d1, self.d2 = d1, d2
self.other1, self.other2 = None, None
def add(attr):
return self.c1.__getattribute__(attr) self.c2.__getattribut__(attr) self.__getattribute__(attr)
c1 = C(1, 2)
c2 = C(3, 4)
c3 = C(5, 6)
c1.other1 = c2
c1.other2 = c2
a1 = c1.add('d1')
a2 = c1.add('d2')
It definitely feels like I should be able to achieve the same type of thing in C without too much hassle. Is this the case? If so, how?
CodePudding user response:
You can't really use a string to get the member without some kind of reflection. However, you can use a pointer to member:
class C {
double add(double C::* ptr){
return linked1->*ptr linked2->*ptr this->*ptr;
}
};
Then call it like:
double a1 = c1.add(&C::d1);
CodePudding user response:
C doesn't have reflection, but you can easily accomplish this task by using a std::(unordered_)map
, eg:
#include <map> // or <unordered_map>
#include <string>
class C{
public:
C* linked1;
C* linked2;
std::map<std::string, double> values; // or std::unordered_map
C(double d1, double d2) {
values["d1"] = d1;
values["d2"] = d2;
}
double add(const std::string& name) const {
return linked1->values.at(name) linked2->values.at(name) values.at(name);
}
};
C c1{1., 2.};
C c2{3., 4.};
C c3{5., 6.};
c1.linked1 = &c2;
c1.linked2 = &c3;
double a1 = c1.add("d1");
double a2 = c1.add("d2");