私はC ++ 11、Qt5.12に取り組んでいます。関数ポインタをマップまたは配列に格納する必要があります。重要なのは、これらのメソッドには異なる戻り型とパラメーター型があるということです。
クラスでいくつかの単純なデータ構造を定義しました。これが私ができる限り簡単な例です:
class TableData
{
public:
enum EnumFieldType
{
FieldType_None = 0,
FieldType_Int,
FieldType_QString
};
enum EnumFieldId
{
FieldId_None = 0,
FieldId_Id,
MaxSystemFieldId = 64
};
int id() const;
void setId(const int _id);
QVariant getFieldValue(int _fieldId);
void setFieldValue(int _fieldId, QVariant _value)
protected:
int id_;
//Here some QMap or QVector with the function pointers
}
class EmployeeData : public TableData
{
public:
enum EnumFieldId
{
FieldId_Name = TableData::MaxSystemFieldId + 1,
FieldId_Age
};
QString name() const;
int age() const;
void setName(const QString &_name);
int setAge(const Int &_age);
protected:
int age_;
QString name_;
}
アイデアは、TableDataに3つのマップを作成することです。
これらのマップは、TableDataサブクラスコンストラクターに入力されます。したがって、サブクラスのインスタンスが構築されたら、次を使用できます。
EmployeeData ed;
ed.setId(5);
ed.setAge(11);
ed.setName("Son Gohan");
または:
EmployeeData ed;
ed.setField(EmployeeData::FieldId_Id, 5);
ed.setField(EmployeeData::FieldId_Age, 11);
ed.setField(EmployeeData::FieldId_Name, "Son Gohan");
これらの最後の呼び出しはTableData :: SetFieldメソッドに移動します。このメソッドは、FieldIdキーを使用してマップmapFieldTypesを調べ、フィールドのタイプを取得する必要があります。次に、セッター関数ポインターを取得し、セッター関数によって要求されたタイプに適切に変換されたQVariantパラメーターを使用して呼び出します。
私はこれについて苦労し、読んで、探して、解決策を探すのに多くの時間を費やしました。ポインタまたはコールバックの配列は同じ関数型である必要があり、std :: functionとstd :: bindはこれを解決しません(配列は同じ関数型である必要があり、bindはすでに事前定義された値を使用するなど)...私は同様のものが必要です変数に適用される(void *)ポインターに、ただし関数ポインターの場合(types mapを使用すると、汎用関数ポインターを必要な関数ポインターテンプレートに効果的にキャストできると思います)。
何か案は?
PD:いくつかのコードの問題やタイプミスについて申し訳ありませんが、実際のコードははるかに複雑であり、可能な限り単純化して緩和しようとしました。
以下のように見えるQtのプロパティシステムはあなたのための完璧なソリューションです。
class TableData : public QObject {
Q_OBJECT
public:
TableData() : QObject(), _id(0) {}
QVariant getFieldValue(const char * fieldName) const {
return property(fieldName);
}
void setFieldValue(const char * fieldName, QVariant _value) {
setProperty(fieldName, _value);
}
int id() const { return _id; }
void setId(int newID) {
_id = newID;
emit idChanged();
}
protected:
Q_PROPERTY(int id
READ id
WRITE setId
NOTIFY idChanged)
int _id;
signals:
void idChanged();
};
class EmployeeData : public TableData {
Q_OBJECT
public:
EmployeeData() : TableData(), _age(-1), _name("") {}
int age() const { return _age; }
void setAge(int newAge) {
_age = newAge;
emit ageChanged();
}
QString name() const { return _name; }
void setName(QString newName) {
_name = newName;
emit nameChanged();
}
protected:
Q_PROPERTY(int age
READ age
WRITE setAge
NOTIFY ageChanged)
int _age;
Q_PROPERTY(QString name
READ name
WRITE setName
NOTIFY nameChanged)
QString _name;
signals:
void ageChanged();
void nameChanged();
};
void TableData::setField(const char *, QVariant);
メソッドは呼び出しますvoid QObject::setProperty(const char *, QVariant);
。この最後はWRITE
、プロパティ値を更新するために、プロパティフィールドで指定したセッターを自動的に呼び出します。次の3つのコードは、まったく同じことを行います。
属性のセッターの使用:
EmployeeData ed;
ed.setId(5);
ed.setAge(11);
ed.setName("Son Gohan");
使用void TableData::setField(const char *, QVariant);
:
EmployeeData ed;
ed.setField("id", 5);
ed.setField("age", 11);
ed.setField("name", "Son Gohan");
使用するvoid QObject::setProperty(const char *, QVariant);
(あなたEmployeeData
もであるためQObject
):
EmployeeData ed;
ed.setProperty("id", 5);
ed.setProperty("age", 11);
ed.setProperty("name", "Son Gohan");
属性の読み取りについても同じです。あなたのQVariant TableData::getField(const char *) const;
方法を呼び出しますQVariant QObject::property(const char *) const;
。この最後はREAD
、プロパティ値を取得するために、プロパティフィールドで指定したゲッターを自動的に呼び出します。次の3つのコードは、まったく同じことを行います。
属性のセッターの使用:
// Using the EmployeeData ed defined above
int id = ed.id(); // id == 5
int age = ed.age(); // age == 11
QString name = ed.name(); // name == "Son Gohan"
使用QVariant TableData::getField(const char *) const;
:
// Using the EmployeeData ed defined above
int id = ed.getField("id").toInt(); // id == 5
int age = ed.getField("age").toInt(); // age == 11
QString name = ed.getField("name").toString(); // name == "Son Gohan"
使用するQVariant QObject::property(const char *) const;
(あなたEmployeeData
もであるためQObject
):
// Using the EmployeeData ed defined above
int id = ed.property("id").toInt(); // id == 5
int age = ed.property("age").toInt(); // age == 11
QString name = ed.property("name").toString(); // name == "Son Gohan"
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加