gpt4 book ai didi

c++ - 在基本模板函数中访问派生类的成员函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:10:49 25 4
gpt4 key购买 nike

我有一个名为 DBDriver 的类,它处理与数据库中给定表的通信。它的公共(public)入口点是一个名为 execute_query() 的函数模板,它执行 SELECT 查询。调用此函数后,将执行一些数据库逻辑,然后使用结果填充提供的容器(模板类型)。这看起来像下面这样:

class DBDriver {

...

template <typename CONT_T>
void execute_query(const std::string& query, CONT_T& container);

...

};

template <typename CONT_T>
void DBDriver::execute_query(const std::string& query, CONT_T& container) {
DBCursor& cursor = ... // some database logic here
populate_container(container, cursor);
}

当然,上面的代码不会编译,因为 populate_container() 没有在 DBDriver 中定义。

DBDriver 应该是纯虚拟的,并且有几个类派生自它(每个涉及的数据库表一个)。每个派生类都将定义自己的 populate_container() 重载,每个相关容器类型都有一个重载。这将类似于以下内容:

class SampleTableDBDriver : public DBDriver {

// ...

populate_container(const ContainerTypeOne& container, DBCursor& cursor);
populate_container(const ContainerTypeTwo& container, DBCursor& cursor);

// ...

};

我最初的尝试没有成功,因为我需要在 DBDriver 中定义一个虚函数模板作为派生类的入口点 populate_container() 重载。 (当然,这种事情在 C++ 中不存在,因此是我的问题。)

是否有针对此类问题的更简洁、惯用的解决方案?

最佳答案

execute_query 是模板函数的原因是您需要一个通用容器。如果您为容器定义一个 Interface 会怎么样?

class IContainer
{};

模板函数不能是虚拟的。因此,您可以使用 Template Method Design Pattern .

class DBDriver 
{
public:
void execute_query(const std::string& query, IContainer **_ppContainer);
{
DBCursor& cursor = ... // some database logic here
populate_container(_ppContainer, cursor);
}

virtual void populate_container(IContainer **_ppContainer, DBCursor &_dbCursor) = 0;
};

让每个派生类都实现populate_container 并提供他们自定义的Container

class SampleTableDBDriver : public DBDriver 
{
public:
class ContainerTypeOne : public IContainer
{};

void populate_container(IContainer **_ppContainer, DBCursor &_dbCursor)
{
ContainerTypeOne *pContainer = new ContainerTypeOne();
//....
(*_ppContainer) = pContainer;
}
};


SampleTableDBDriver oSampleDriver;
IContainer *pContainer = NULL;
std::string szQuery = // some query ;
oSampleDriver.execute_query(szQuery, &pContainer);
if(pContainer != NULL)
{
SampleTableDBDriver::ContainerTypeOne *pSampleDriverContainer =
dynamic_cast<SampleTableDBDriver::ContainerTypeOne*>(pContainer);

//use pSampleDriverContainer
}

编辑:用于支持多个容器。

在您的原始设计中,populate_container 似乎在派生类中过载。在那种情况下,您仍然会在调用 execute_query 时从外部传递 exact 容器。使用此 Template Method 设计可以完成同样的事情。然后,您需要破译 populate_container 函数内的容器类型,如下所示:

新签名:int populate_container(IContainer *_pContainer, DBCursor &_dbCursor)

int populate_container(IContainer *_pContainer, DBCursor &_dbCursor) 
{
if(dynamic_cast<ContainerTypeOne *>(_pContainer) != NULL)
{
ContainerTypeOne *pContainerOne = _pContainer;
//populate the result by using pContainerOne
return 1;
}

if(dynamic_cast<ContainerTypeTwo *>(_pContainer) != NULL)
{
ContainerTypeOne *pContainerTwo = _pContainer;
//populate the result by using pContainerTwo
return 1;
}

//no, I do not support the container you passed.
return 0;
}

SampleTableDBDriver oSampleDriver;
SampleTableDBDriver::ContainerTypeOne oSampleContainerTypeOne;
std::string szQuery = // some query ;
if(oSampleDriver.execute_query(szQuery, &oSampleContainerTypeOne) != 0)
{
//use oSampleContainerTypeOne;
}

关于c++ - 在基本模板函数中访问派生类的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41844099/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com