Qt&C ++:異なる戻り値とパラメーター型を持つ関数ポインターの配列

ブル

私は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つのマップを作成することです。

  • QMap mapFieldTypes
  • QMap mapGetters
  • QMap

これらのマップは、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]

編集
0

コメントを追加

0

関連記事

分類Dev

関数の配列-異なる関数を持つポインターの戻り値(C)

分類Dev

同じ名前とパラメーター、異なる戻り値の型を持つC ++メンバー関数

分類Dev

戻り値の型が異なる関数ポインタC

分類Dev

変数のパラメーター化とタイプを持つC関数ポインター

分類Dev

配列への C++ ポインターに関するエラー: 単項 * の無効な型引数 ('int を持っている)、割り当ての左側のオペランドとして左辺値が必要です

分類Dev

C ++で自動戻り値の「型」を持つテンプレートメンバーへのポインタ?

分類Dev

異なる値のパラメーターに割り当てられたCポインター引数

分類Dev

C-名前付きパラメーターを持つ関数ポインター型

分類Dev

C ++:特定の(double ...)ポインターパラメーターを持つ関数でvoid *関数を使用して関数をオーバーロードする

分類Dev

パラメータとしてポインタを1つだけ使用して、関数内のc配列を実行することは可能ですか?

分類Dev

タイプ 'const C s [N]'(タイプCの要素の固定サイズ配列)のパラメーターを持つテンプレート関数

分類Dev

cの関数のパラメーターとしての2D配列へのポインター

分類Dev

メンバー関数を持つクラス内で使用される、パラメーターとして関数へのポインターを持つC ++外部関数

分類Dev

2つの関連する型を指すCのポインターの配列を維持する

分類Dev

c#パラメーターを持つ関数の戻り値で実行されている非同期タスク

分類Dev

C ++:constメンバー関数から非constポインターパラメーターを受け取る外部関数にポインター値のメンバー変数を渡すことができるのはなぜですか?

分類Dev

2つの異なるタイプの数値変数に `std :: max()`関数を使用すると、c ++コンパイラでエラーが発生する理由

分類Dev

変数パラメーターと戻り値の型を使用してC#関数のリストを実行する

分類Dev

異なるパラメーターを持つ関数に関数を渡して実行する方法c#

分類Dev

関数のパラメーター値に基づいて、C ++で関数の戻り値の型を動的に変更する方法はありますか?

分類Dev

パラメータとしてOutputIteratorを持つメンバー関数を必要とするC ++の概念

分類Dev

2つの異なるタイプをC#の関数パラメーターに渡す方法は?

分類Dev

関数C ++へのパラメーターとして変数パラメーターを持つ関数

分類Dev

C ++の関数の戻り値の型としてポインターまたは参照を使用する際の経験則はありますか?

分類Dev

関数ポインタのconst配列を持つc ++テンプレート静的クラス

分類Dev

戻り値の型のみが異なるC ++の複数のインターフェイス?

分類Dev

cの未知の型配列で最大要素を見つける方法(関数へのポインターを使用)

分類Dev

Cでの関数配列のパラメータ受け渡し/戻り、

分類Dev

C ++:型特性ごとに異なる戻り値の型を持つ関数を有効にする

Related 関連記事

  1. 1

    関数の配列-異なる関数を持つポインターの戻り値(C)

  2. 2

    同じ名前とパラメーター、異なる戻り値の型を持つC ++メンバー関数

  3. 3

    戻り値の型が異なる関数ポインタC

  4. 4

    変数のパラメーター化とタイプを持つC関数ポインター

  5. 5

    配列への C++ ポインターに関するエラー: 単項 * の無効な型引数 ('int を持っている)、割り当ての左側のオペランドとして左辺値が必要です

  6. 6

    C ++で自動戻り値の「型」を持つテンプレートメンバーへのポインタ?

  7. 7

    異なる値のパラメーターに割り当てられたCポインター引数

  8. 8

    C-名前付きパラメーターを持つ関数ポインター型

  9. 9

    C ++:特定の(double ...)ポインターパラメーターを持つ関数でvoid *関数を使用して関数をオーバーロードする

  10. 10

    パラメータとしてポインタを1つだけ使用して、関数内のc配列を実行することは可能ですか?

  11. 11

    タイプ 'const C s [N]'(タイプCの要素の固定サイズ配列)のパラメーターを持つテンプレート関数

  12. 12

    cの関数のパラメーターとしての2D配列へのポインター

  13. 13

    メンバー関数を持つクラス内で使用される、パラメーターとして関数へのポインターを持つC ++外部関数

  14. 14

    2つの関連する型を指すCのポインターの配列を維持する

  15. 15

    c#パラメーターを持つ関数の戻り値で実行されている非同期タスク

  16. 16

    C ++:constメンバー関数から非constポインターパラメーターを受け取る外部関数にポインター値のメンバー変数を渡すことができるのはなぜですか?

  17. 17

    2つの異なるタイプの数値変数に `std :: max()`関数を使用すると、c ++コンパイラでエラーが発生する理由

  18. 18

    変数パラメーターと戻り値の型を使用してC#関数のリストを実行する

  19. 19

    異なるパラメーターを持つ関数に関数を渡して実行する方法c#

  20. 20

    関数のパラメーター値に基づいて、C ++で関数の戻り値の型を動的に変更する方法はありますか?

  21. 21

    パラメータとしてOutputIteratorを持つメンバー関数を必要とするC ++の概念

  22. 22

    2つの異なるタイプをC#の関数パラメーターに渡す方法は?

  23. 23

    関数C ++へのパラメーターとして変数パラメーターを持つ関数

  24. 24

    C ++の関数の戻り値の型としてポインターまたは参照を使用する際の経験則はありますか?

  25. 25

    関数ポインタのconst配列を持つc ++テンプレート静的クラス

  26. 26

    戻り値の型のみが異なるC ++の複数のインターフェイス?

  27. 27

    cの未知の型配列で最大要素を見つける方法(関数へのポインターを使用)

  28. 28

    Cでの関数配列のパラメータ受け渡し/戻り、

  29. 29

    C ++:型特性ごとに異なる戻り値の型を持つ関数を有効にする

ホットタグ

アーカイブ