C++ 派生类的部分类模板专门化
我正试图为嵌入式Linux系统编写一个在LCD上绘制用户界面元素的程序。我有一个名为C++ 派生类的部分类模板专门化,c++,template-specialization,C++,Template Specialization,我正试图为嵌入式Linux系统编写一个在LCD上绘制用户界面元素的程序。我有一个名为Widget的基类,它实现了绘图和擦除等基本功能,并具有x/y位置和宽度/高度等属性。然后,我使用派生类Label、Button和ProgressBar,它们分别添加自己的属性(文本、焦点和值) 我的问题是,我想创建一个名为WidgetArray的模板容器类,它将自动生成一个小部件网格,并批量编辑它们的属性。但是,例如,如果widgetary包含一个函数,该函数接受字符串向量并将每个字符串分配给标签的text属性
Widget
的基类,它实现了绘图和擦除等基本功能,并具有x/y位置和宽度/高度等属性。然后,我使用派生类Label
、Button
和ProgressBar
,它们分别添加自己的属性(文本、焦点和值)
我的问题是,我想创建一个名为WidgetArray
的模板容器类,它将自动生成一个小部件网格,并批量编辑它们的属性。但是,例如,如果widgetary
包含一个函数,该函数接受字符串向量并将每个字符串分配给标签的text
属性,如果我声明了widgetary
的一个实例,其中包含ProgressBar
s(没有文本属性),编译器会抱怨。这似乎是模板专门化的完美案例。我正在阅读关于模板专业化的页面,看到了以下内容:
当我们为一个模板类声明专门化时,我们还必须定义它的所有成员,甚至那些完全等于泛型模板类的成员,因为从泛型模板到专门化没有成员的“继承”
请告诉我有办法解决这个问题。WidgetArray
的绝大多数成员函数对于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);
}
}
};
模板
类WidgetArray{
受保护的:
性病媒儿童;
int列,x,y;
int元素w,元素h;
int x_填充,y_填充;
公众:
WidgetArray(){
列=1;
调整大小(1);
x=0;
y=0;
}
WidgetArray(整数x_英寸,整数y_英寸,整数大小,整数列){
无符号整数计数器1=0,计数器2=0;
列=列;
x=x_英寸;
y=y_英寸;
元素w=10;
元素h=10;
x_=0;
y_=0;
调整大小(大小);
用于(无符号ii=0;ii列){
计数器1=0;//列号
计数器2++;//行号
}
在(ii)处,x=counter1*(元素w+x+x);
在(ii)处,y=counter2*(元素h+y+y);
子元素。在(ii)处。宽度=元素w;
儿童。在(ii)处。身高=元素_h;
}
}
void draw_children(std::vector和cmd_str){
对于(无符号ii=0;ii列){
计数器1=0;//列号
计数器2++;//行号
}
在(ii)处,x=counter1*(元素w+x+x);
在(ii)处,y=counter2*(元素h+y+y);
子元素。在(ii)处。宽度=元素w;
儿童。在(ii)处。身高=元素_h;
}
返回1;
}
int赋值_文本(标准::向量文本){
对于(unsigned ii=0;ii,听起来您想要的只是一个模板基类,它包含所有特定于这两种方法的方法,然后从中继承。例如:
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
};
模板
结构基
{
受保护的:
性病媒儿童;
~base(){}
公众:
void draw_children();
//所有模板参数T通用的其他方法
};
类WidgetArrayString
:公共基地
{
//仅特定于字符串的方法
};
类WidgetArrayProgressBar
:公共基地
{
//仅特定于进度条的方法
};
我试图理解为什么您首先要专门化您正在描述的案例。添加的小部件必须符合WidgetArray处理它们的方式。除此之外的任何内容都可以在派生中扩展,即类ProgressBarArray:public WidgetArray
,并将进度条的方法添加到那门课;不是专业化?还是我完全误解了问题和最终目标?换句话说,我不确定你为什么认为专业化是正确的答案?好吧,现在我觉得自己很傻。那会有用的。我想我只是在脑子里想,既然我在使用模板,那一定是解决方案。谢谢,我没意识到你可以用它Beezum如果是这样的话,那么你真的应该烤你的面条了。