C++ 按变量值访问结构属性

C++ 按变量值访问结构属性,c++,struct,getter-setter,C++,Struct,Getter Setter,我的类中有一个结构“margin”,有4个属性。我没有编写四种不同的getter/setter方法,而是认为我可以用更好的方式: class myClass { private: struct margin { int bottom; int left; int right; int top; } public: struct getMa

我的类中有一个结构“margin”,有4个属性。我没有编写四种不同的getter/setter方法,而是认为我可以用更好的方式:

class myClass {
    private:
        struct margin {
            int bottom;
            int left;
            int right;
            int top;
        }
    public:
        struct getMargin();
        void setMargin(string which, int value);
};
但是如何在函数
setMargin()
中设置与字符串“which”对应的结构的属性呢?例如,如果我调用
myClass::setMargin(“left”,3)
,那么如何将“margin.left”设置为“3”?最好是在保持结构的同时?我真的搞不懂

另外,这真的比编写许多getter/setter方法好吗


谢谢

首先,你的想法很糟糕……:)

请注意,您甚至没有
边距
成员(添加在下面)

如果您不希望每个属性都使用setter/getter,我会为此使用
enum

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);
};
您可以使用“相对指针”,它指向从结构地址到指向特殊元素的距离。例如:

SetMargin(FIRST,5);
第一个值来自枚举值,为0

SetMargin(SECOND,100);
第二个是4,因为在我的系统中int是4字节

实施:

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

如果您可以公开margin,则可以取消get、set方法:

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

myClass mc;

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

我更喜欢吕琴或吉尔的建议。但是,如果您确实需要通过字符串进行查找,那么最好使用关联容器进行查找

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;
    }
};
class-MyClass{
std::mapm;
公众:
bool setMargin(std::string which,int值){
std::map::迭代器i=m_.find(which);
如果(i==m_z.end())返回false;
i->second=值;
返回true;
}
};

只有当您有一个动态界面,允许您的用户按名称定义自己的边距时,这才有用。

“顺便说一句,这真的比编写许多getter/setter方法好吗?”-不,更糟糕。在需要时编写get/set方法没有什么错。它们并不总是必需的。@EdS。但是在这种情况下需要它们吗?这意味着写8个方法而不是2个,没有明显的优势(在我看来)。还是有优势?那么,让我们澄清一下;在变量名中键入字符串是一个可怕的想法。把那个扔了吧。根据你的问题(“他们是否需要”),嗯,我不知道;这取决于你的申请。您是否需要对属性进行任何形式的验证?如果答案是明确的“不”,那么不,你根本不需要包装它们。+1对我来说是一个挑战性的问题。^^^@EdS。嗯,好的。谢谢你的回答!但是你也建议写getter和setter方法吗?@Frog我认为这只是偏好的问题。现在考虑一下,我也更喜欢使用带有enum的单一方法,而不是setter/getter。为什么要使用margin结构而不是int[4]?那你就不需要一个switch@GirIDK如何回答这个问题。面向对象原则?这是C++而不是C的事实?因为它更干净?封装?单一责任?…封装只在外部起作用。作为实现细节,
int[4]
就可以了。然后开关不见了<代码>边[which]=值
;`。这就是说,你失去了一些验证,可能想检查有效范围,所以,嗯。虽然这不是我想要的,但请支持这个好主意。根据你使用的平台,
int
的大小可能会有所不同,这不是真的吗?那么这段代码可能不起作用了?那么您可以用sizeof(int)和sizeof(int)*2交换枚举值,以此类推。。。。你可以让它更独立不是我需要的,而是一个伟大的解决方案!要找到一个简单的输入错误所产生的恼人的bug需要几个小时:
setMargin(“rigth”,5)
@quinmars:正如我在回答中所说的,它只作为动态接口的数据结构,而不是API。例如,如果允许编辑器的用户动态创建页边距并命名它们。我假设编辑器的GUI会列出它知道的用户名称,或者在用户想要添加新的边距名称时提示用户。
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;
}
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;
    }
};