简体   繁体   中英

Access struct property by variable value

I've got a struct "margin" in my class with 4 properties. Instead of writing four different getter/setter methods, I figured I could do it in a better way:

class myClass {
    private:
        struct margin {
            int bottom;
            int left;
            int right;
            int top;
        }
    public:
        struct getMargin();
        void setMargin(string which, int value);
};

But how can I set the property of the struct corresponding with the string "which" from within the function setMargin() ? For example, if I call myClass::setMargin("left", 3) , how can I then set "margin.left" to "3"? Preferably while keeping the struct POD ? I really can't figure this out...

And on a side note, is this really better than writing many getter/setter methods?

Thanks!

First, your idea is terrible... :)

Note you don't even have a margin member (added below)

I'd use an enum for this, if you don't want setters/getters for each property:

class myClass {
    private:
        struct margin {
            int bottom;
            int left;
            int right;
            int top;
        } m;  // <--- note member variable
    public:
        enum Side
        {
           bottom, left, rigth, top
        };
        struct getMargin();
        void setMargin(Side which, int value);
};

and have a switch statement inside setMargin .

void myClass::setMargin(Side which, int value)
{
    switch (which)
    {
        case bottom:
           m.bottom = value;
           break;
    //....
    }
}
class myClass {
private:
    int margin[4];
public:
    enum Side
    {
       bottom, left, rigth, top
    };
    void setMargin(Side which, int value);
};

void myClass::setMargin(Side which, int value)
{
    margin[which]=value;
}

Either Luchian's or Gir's suggestion would be my preference. If you really want need a look up by a string, though, it is probably best to do that with an associative container.

class MyClass {
    std::map<std::string, int> m_;
public:
    bool setMargin(std::string which, int value) {
        std::map<std::string, int>::iterator i = m_.find(which);
        if (i == m_.end()) return false;
        i->second = value;
        return true;
    }
};

This is only useful if you have a dynamic interface that allows your user to define their own margins by name.

You can use "relative pointer" which points the distance from the address of struct to point a special element. For example:

SetMargin(FIRST,5);

Which FIRST is from an enum value and is 0.

SetMargin(SECOND,100);

SECOND is 4 since int is 4 bytes in my system

implementation:

void SetMargin(enum margin_elements,int a)
{
    int *relative=struct_pointer+(int*)margin_elements;
    *relative_pointer=a;
     return;
 }

If you can make margin public, you can get rid of get,set methods:

class myClass {
    public:
        struct Margin {
            int bottom;
            int left;
            int right;
            int top;
        };
        Margin margin;
};

myClass mc;

mc.margin.bottom = mc.margin.left;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM