1

組み込みLinuxシステムのLCDにユーザーインターフェイス要素を描画するプログラムを作成しようとしています。Widget描画や消去などの基本機能を実装し、x/yの位置や幅/高さなどの属性を持つという基本クラスがあります。次に、独自の属性(それぞれ、テキスト、フォーカス、および値)を追加するクラスLabel、、Buttonを派生させました。ProgressBar

WidgetArray私の問題は、ウィジェットのグリッドを自動的に生成し、それらのプロパティをまとめて編集するというテンプレートコンテナクラスを作成したいということです。ただし、WidgetArrayたとえば、文字列のベクトルを受け取り、各文字列をのtextプロパティに割り当てる関数が含まれている場合、 (テキスト属性を持たない)を含むLabelインスタンスを宣言すると、コンパイラは文句を言います。これは、テンプレートの特殊化に最適なケースのようです。私はcplusplus.comでテンプレートの特殊化に関するページを読んでいて、これを見ました:WidgetArrayProgressBar

テンプレートクラスの特殊化を宣言するときは、汎用テンプレートから特殊化へのメンバーの「継承」がないため、汎用テンプレートクラスと完全に等しいメンバーも含めて、そのすべてのメンバーも定義する必要があります。

これを回避する方法があることを教えてください。のメンバー関数の大部分は、のWidgetArrayすべての派生クラスに対して完全に有効であり、派生クラスに1つの特殊な関数を追加するためだけに、コード全体Widgetをコピーして貼り付ける必要があるのは非常に愚かなことのようです。WidgetArray

これが私が持っているコードのやや簡略化されたバージョンです:

template<class T>
class WidgetArray {
protected:
    std::vector<T> children;
    int columns, x, y;
    int element_w, element_h;
    int x_padding, y_padding; 
public:
    WidgetArray() {
        columns = 1;
        children.resize(1);
        x = 0;
        y = 0;
    }
    WidgetArray(int x_in, int y_in, int size, int cols) {
        unsigned int counter1=0, counter2=0;
        columns = cols;
        x = x_in;
        y = y_in;
        element_w = 10;
        element_h = 10;
        x_padding = 0;
        y_padding = 0;
        children.resize(size);
        for (unsigned ii = 0; ii < size; ii++) {
            if (counter1 > columns) {
                counter1 = 0; //column number
                counter2++; //row number
            }
            children.at(ii).x = counter1*(element_w + x_padding) + x;
            children.at(ii).y = counter2*(element_h + y_padding) + y;
            children.at(ii).width = element_w;
            children.at(ii).height = element_h;
        }
    }        
    void draw_children(std::vector<unsigned char>& cmd_str){
        for (unsigned ii=0; ii < children.size(); ii++) children.at(ii).draw(cmd_str);
    }
    void redraw_children(std::vector<unsigned char>& cmd_str) {
        for (unsigned ii=0; ii < children.size(); ii++) {
            children.at(ii).erase(cmd_str);
            children.at(ii).draw(cmd_str);
        }
    }
    void erase_children(std::vector<unsigned char>& cmd_str) {
        for (unsigned ii=0; ii < children.size(); ii++) children.at(ii).erase(cmd_str);
    }
    int reform(int num_elements, int cols, int x_in, int y_in) {
        unsigned int counter1=0, counter2=0;

        children.clear();
        children.resize(num_elements);
        columns = cols;
        x = x_in;
        y = y_in;
        for (unsigned ii = 0; ii < children.size(); ii++) {
            if (counter1 > columns) {
                counter1 = 0; //column number
                counter2++; //row number
            }
            children.at(ii).x = counter1*(element_w + x_padding) + x;
            children.at(ii).y = counter2*(element_h + y_padding) + y;
            children.at(ii).width = element_w;
            children.at(ii).height = element_h;
        }
        return 1;
    }
    int assign_text(std::vector<string> text) {
        for (unsigned ii=0; ii<children.size() || ii < text.size(); ii++) {
            //This is only valid if my type is a Button or Label but I want
            //the rest of the code for WidgetArray to be valid for any derived
            //class of Widget
            children.at(ii).text = text.at(ii);
        }
    }
};

私の質問が明確であることを願っています。周りを見回して、テンプレートの特殊化に関する投稿がたくさんありますが、私の質問に答えているように見えるものは見つかりませんでした。

4

1 に答える 1

2

必要なのは、両方に固有のすべてのメソッドを含むテンプレート化された基本クラスであり、それらを継承するように思えます。例えば:

template <typename T>
struct base
{
protected:
    std::vector<T> children;
    ~base() { }

public:
    void draw_children();
    //Other methods common to all template parameters T

};


class WidgetArrayString
    : public base<std::string>
{
    //Methods specific only to strings
};

class WidgetArrayProgressBar
    : public base<ProgressBar>
{
    //Methods specific only to progress bar
};
于 2013-03-18T00:49:13.937 に答える