Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;模板:从基类调用派生模板类的成员函数_C++_Templates_Inheritance_Polymorphism - Fatal编程技术网

C++ C++;模板:从基类调用派生模板类的成员函数

C++ C++;模板:从基类调用派生模板类的成员函数,c++,templates,inheritance,polymorphism,C++,Templates,Inheritance,Polymorphism,我目前正在开发一个电子表格应用程序,但我在模板方面遇到了问题。 模板的每个单元格都可以包含一个变量,该变量可以是任何标准类型 相关类是电子表格,其最重要的成员变量是SheetCells,它具有 键入vector。CellBase类是一个抽象类,CellField就是从中派生出来的 派生的,后者是存储恰好对应于一个单元格的一段数据的模板类 电子表格的一部分 我还有一个类,SheetView,它最终必须显示电子表格。(为了简单起见, 假设这个类拥有对其他所有类的完全访问权限。)这个类并不真正关心什么

我目前正在开发一个电子表格应用程序,但我在模板方面遇到了问题。 模板的每个单元格都可以包含一个变量,该变量可以是任何标准类型

相关类是
电子表格
,其最重要的成员变量是
SheetCells
,它具有 键入
vector
CellBase
类是一个抽象类,
CellField
就是从中派生出来的 派生的,后者是存储恰好对应于一个单元格的一段数据的模板类 电子表格的一部分

我还有一个类,
SheetView
,它最终必须显示电子表格。(为了简单起见, 假设这个类拥有对其他所有类的完全访问权限。)这个类并不真正关心什么类型 每个单元格的值都是,因为它无论如何都会将所有内容转换为字符串。然而,我的问题是写作
电子表格
的成员函数,返回包含数据的字符串。我的第一个想法是写一个函数
std::string SpreadSheet::getDataFromSheet(int行,int列)
将调用该函数
返回(std::to_string(SheetCells[row][column]->getData())
,其中
getData()
CellField
的成员函数,返回 属于
T
类型的东西。 但是,由于
SheetCells
包含指向
CellBase
类的指针,我必须使
getData
成为
CellBase
的成员, 但这是不可能的,因为我希望
getData()
返回类型为
T
的变量,该类型与模板类的类型相同
CellField

所有类别定义的相关部分如下所示

//SpreadSheet

class Spreadsheet
{

private:
    int _height, _width;

public:
    Spreadsheet(int newHeight, int newWidth);
    ~Spreadsheet();
    string getData(int row, int column);
    vector< vector<CellBase*> > SheetCells;

};



//CellBase

class CellBase
{
    public:
        CellBase();
        virtual ~CellBase();
};



//CellField

template<typename T>
class CellField : public CellBase
{
    public:
        CellField(T newValue);
        virtual ~CellField();
        T getData();
        T _value;
};
//电子表格
班级电子表格
{
私人:
内部高度,内部宽度;
公众:
电子表格(int-newHeight、int-newWidth);
~电子表格();
字符串getData(int行,int列);
载体<载体>细胞;
};
//牢房
类细胞库
{
公众:
CellBase();
虚拟~CellBase();
};
//CellField
模板
类别CellField:公共CellBase
{
公众:
CellField(T-newValue);
虚~CellField();
T getData();
T_值;
};
简而言之,我希望能够从
电子表格
调用
getData()
,但是后者的成员变量 仅包含指向
CellBase
类的指针(但这些类实际上属于
CellField


我已经研究过类似的问题,但它们似乎都没有解决基类成员函数调用模板
class
函数的问题,其中后者和前者需要返回
T
类型的变量。也许<代码>空白>代码>指针会起作用?< /p> ,因为C++是强类型语言,不能直接调用它们,因为编译器不能计算函数的返回值是什么。 您需要做的是,将其全部映射到一个公共接口。你应该问的问题是:我真正需要从CelField那里得到什么信息?也许您只需要值的字符串表示,然后您可以执行以下操作:

class CellBase
{
    virtual std::string getData()=0;
};

template<typename T>
class CellField : public CellBase
{
    std::string getData(){//some implementation}
};
类CellBase { 虚拟std::string getData()=0; }; 模板 类别CellField:公共CellBase { std::string getData(){//some实现} };
另一个选项是使用
boost::any
,它可以包含您喜欢的任何类型。如果您不需要实际干扰返回值,而只需要将其传递给使用“任意参数”的其他函数,那么这一点尤其有用。但是,为了真正使用该值,您仍然必须使用
boost::any_cast()
将其强制转换为特定类型,因此需要知道所需的类型,并在类型错误时进行适当的错误处理。

一种可能的解决方案是雇佣访问者,具体如下:

Class Visitor
{
   virtual ~Visitor(void) {}
   virtual void visit(CellBase<int> *cell) {}
   virtual void visit(CellBase<float> *cell) {}
...
} ;

class CellBase
{
public:
     CellBase();
     virtual ~CellBase();
     virtual void accept(Visitor *v) { v->visit(this) ;}
};

class DataGetterVisitor : public Visitor
{
public:
    virtual void visit(CellBase<int> *cell) 
    {
       // here I know how to make the transformation

    }
    virtual void visit(CellBase<float> *cell) {}
    string text ;
} ;

string dataGetter(CellBase *cell)
{
    DataGetterVisitor visitor ;
    cell->accept(visitor);
    return visitor.text ;
}
类访问者
{
虚拟~Visitor(void){}
虚拟无效访问(CellBase*cell){}
虚拟无效访问(CellBase*cell){}
...
} ;
类细胞库
{
公众:
CellBase();
虚拟~CellBase();
虚拟无效接受(访问者*v){v->visit(this);}
};
类DataGettServiceSitor:公共访问者
{
公众:
虚拟无效访问(CellBase*cell)
{
//在这里,我知道如何进行转换
}
虚拟无效访问(CellBase*cell){}
字符串文本;
} ;
字符串数据获取程序(CellBase*cell)
{
数据获取服务访问者;
单元格->接受(访客);
返回visitor.text;
}

许多可能的答案。。。我将使用虚拟纯函数“getData”,它返回一个boost::any,它允许您存储许多不同的类型这正是我所需要的。编译时没有错误并生成正确的结果。我建议使用
override
关键字以防止将来出现问题(例如,通过重命名函数)