0

クラスのメンバーにアクセスするときに、クラスがプロキシとして機能することは何とか可能ですか? もちろん、最も簡単な方法はゲッター/セッターを作成することですが、コードを肥大化させるすべてのセッターを自分で作成する必要があるため、これは柔軟性がなくエレガントではありません。

問題は、一部のデータがマイクロコントローラーのプログラムにあるという事実を抽象化したいことです。基本的にはそれが欲しい

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;
4

1 に答える 1

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->member次に、 orを書くことができobject->member = member、代入演算子が作業を行います。

これは私が考えることができる最もクリーンなソリューションです。オペレーターは、->この種のことを実際には意図していません。

もちろん、使用する型ごとに新しいラッパー クラスを定義したくない場合は、テンプレート クラスを使用できます。

于 2013-06-04T19:16:46.190 に答える