![](/img/trans.png)
[英]is it safe to calling a member function not defined on the base class from of a derived class in c++?
[英]C++ templates: Calling member function of derived template class from base class
我目前正在處理電子表格應用程序,但是模板存在問題。 模板的每個單元格都可以包含一個變量,該變量可以是任何標准類型。
相關的類是SpreadSheet
,其最重要的成員變量是SheetCells
,其類型為vector< vector<CellBase*> >
。 CellBase
類是從中CellField<T>
的抽象類,后者是模板類,用於存儲與電子表格的一個單元格完全對應的一條數據。
我還有另一個類SheetView
,該類最終必須顯示電子表格。 (為簡單起見,假定該類具有對其他所有類的完全訪問權限。)此類實際上並不關心每個單元格的值是什么類型,因為無論如何它都會將所有內容轉換為字符串。 但是,我的問題是編寫SpreadSheet
的成員函數,該成員函數返回包含數據的字符串。 我最初的想法是寫一個函數std::string SpreadSheet::getDataFromSheet(int row, int column)
說SheetView
會叫,然后該函數會做return (std::to_string(SheetCells[row][column] -> getData()))
,其中getData()
是CellField<T>
的成員函數,可以CellField<T>
類型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;
};
簡而言之,我希望能夠從SpreadSheet
調用getData()
,但是后者的成員變量僅包含指向CellBase
類的指針(但這些類實際上是CellField<T>
類型的)。
我已經看過類似的問題,但它們似乎都沒有解決調用模板class<T>
函數的基類成員函數的問題,后者和前者需要返回類型T
的變量。 也許void*
指針會起作用?
由於C ++是一種強類型語言,因此您不能以這種方式直接調用它們,因為編譯器將無法弄清楚該函數的返回值是什么。
您需要做的就是將它們全部映射到一個通用接口。 您應該問的問題是:CelField我真正需要什么信息? 也許您需要的只是值的字符串表示形式,那么您可以執行以下操作:
class CellBase
{
virtual std::string getData()=0;
};
template<typename T>
class CellField : public CellBase
{
std::string getData(){//some implementation}
};
另一個選擇是使用boost::any
,它可以包含您喜歡的任何類型。 如果您不需要實際干擾返回的值,而只是將其傳遞給帶有“任意參數”的其他函數,則這特別有用。 但是,為了真正使用該值,您仍然必須使用boost::any_cast<T>()
將其轉換為特定類型,因此需要知道您期望的類型並在類型錯誤的情況下進行正確的錯誤處理。
可能的解決方案是雇用訪客,方法如下:
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 ;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.