【问题标题】:Proxy member access代理成员访问
【发布时间】:2013-06-04 18:19:15
【问题描述】:

类在访问其成员时是否有可能充当代理?最简单的方法当然是编写 getter/setter,但这既不灵活又不优雅,因为您必须自己编写所有的 setter,这会使代码膨胀。

问题是我想抽象出一些数据位于微控制器程序中的事实。基本上我想要那个

MemberType member = object->member; // won't work if object lies in progmem

被翻译成类似的东西

MemberType member; // Allocate memory in RAM for the member
memcpy_P(&member, 
         &object->member, // assuming that this gives a valid pointer to the member
         sizeof(MemberType));

在嵌入式 C 中,可以使用地址空间__flash 来做类似的事情。不幸的是,C++ 不支持这一点。

所以我考虑过重载operator->()。不幸的是,operator->() 没有得到任何您要访问的成员的信息(顺便说一句:为什么 wtf?-> 的唯一目的是访问成员,那么为什么有人要丢弃这些信息?)。 . 根本无法被覆盖。

有人知道如何解决这个问题吗?当然,语法不一定是->。如果可以使用一些深奥的模板构造,我也会很高兴。我不太了解 C++,也许根本不可能。 C++ 在元编程方面似乎有点不灵活。

编辑:在得到答案的启发后,我现在决定使用包装类并覆盖强制转换运算符。

template<typename Type>
class InProgmem {
  Type const self; // InProgmem<Type> should be as big as Type
  InProgmem(Type val) : self(val) {} // Keep the compiler quiet
public:
  operator Type() const {
    Type out; 
    memcpy_P(&out, this, sizeof(Type));
    return out;
  }
} __attribute__((packed));

// Example use:
PROGMEM prog_uchar foo = 14;
class Test {
public:
  InProgmem<unsigned char> bar;
};
Test *baz = (Test*)&foo;
unsigned char bar = baz->bar;

【问题讨论】:

    标签: c++ avr address-space


    【解决方案1】:

    您可以创建一个新类ProgmemMemberType 并定义一些赋值运算符以在内存空间之间进行转换。

    const MemberType &MemberType::operator=(const ProgmemMemberType &other)
    {
        memcpy_P(this, 
                 other.progMemPointer(),
                 sizeof(MemberType));
        return *this;
    }
    
    const ProgmemMemberType &ProgmemMemberType::operator=(const MemberType &other)
    {
        // Whatever the reverse of memcpy_P is...
        return *this;
    }
    

    然后你可以写MemberType member = object-&gt;memberobject-&gt;member = member,赋值操作符会做的工作。

    这是我能想到的最干净的解决方案; -&gt; 运算符并不适合这种事情。

    当然,如果您不想为您使用的每种类型定义一个新的包装类,您可以使用模板类。

    【讨论】:

    • 谢谢。这对我不起作用,因为我打算包装像 int 这样的原始类型,但我给了我正确的灵感。我只是使用了一个虚拟包装模板类并覆盖了强制转换运算符。
    猜你喜欢
    • 2015-02-25
    • 1970-01-01
    • 2014-07-29
    • 1970-01-01
    • 2021-01-02
    • 2012-01-13
    • 2012-10-18
    相关资源
    最近更新 更多