c++ - 如何使用模板和继承来更正和改进此 C++ 代码?

标签 c++ design-patterns templates inheritance

我正在学习 C++,大致知道我想做什么,但我做错了,我很累。做这样的事情的最好方法是什么(首先是正确的方法):

// Query.hpp
class Query {
public:
 Query();

 template<typename T>
 std::vector<boost::shared_ptr<BaseResult> > run();

private:
 std::string sql;
};

// Firstly, something like this:
// I would like to do the equivalent of passing in a type T that would be
// derived from BaseResult and create a new instance of it when adding
// to vector of BaseResult:
template<typename T>
std::vector<boost::shared_ptr<BaseResult> > Query::run() {
 std::vector<boost::shared_ptr<BaseResult> > results;

 // ResultSet is from the mysql c++ connector
 boost::shared_ptr<sql::ResultSet> res(stmt->executeQuery(this->sql));

 // I want to add a new T to results here
 while (res->next()) {
  results.push_back(new T(res));
 }

 // RVO prevents copy in release - yes?
 return results;
}

// Query.cpp
Query::Query() {
}


// main.cpp
void foo(const std::vector<boost::shared_ptr<BaseResult> >& results) {
 // loop through calling virtual method on each item
}

int main(int argc, char* argv[]) 
 // Determine query type
 ProgramOptions opts(argc, argv);

 // Should this indeed be a pointer because
 // of code below or is it wrong?
 std::vector<boost::shared_ptr<BaseResult> >* results;

    // Secondly, something like this:
 if (opts.getquerytype() == "type1") {

  // I'd like to get a
  // std::vector<boost::shared_ptr<BaseResult> > returned here
  // containing many instances of a
  // type derived from BaseResult

  // I'd like to be able to do something like this
  // Is this assignment correct?
        *results = getQuery().run<DerivedResult>();
 }
 else {
  // I'd like to get a
  // std::vector<boost::shared_ptr<BaseResult> > returned here
  // containing many instances of a
  // different type derived from BaseResult

  // I'd like to be able to do something like this
  // Is this assignment correct?
        *results = getQuery().run<DifferentDerivedResult>();
 }

    foo(results);
}

最佳答案

首先,你的分配不正确

*results = getQuery().run<DifferentDerivedResult>();

取消引用一个未初始化的指针!

我会对您的代码做一些更改,首先,必须使用 vector<...>到处都会诱发RSI,typedef

class Query {
public:

 // Query::ResultType
 typedef std::vector<boost::shared_ptr<BaseResult> > ResultType; 

 Query();

 // next, pass in the vector where the results will be stored...
 template<typename T>
   void run(ResultType& records);

private:
 std::string sql;
};

现在执行:

template<typename T>
void Query::run(ResultType& records) {

 // ResultSet is from the mysql c++ connector
 boost::shared_ptr<sql::ResultSet> res(stmt->executeQuery(this->sql));

 // I want to add a new T to results here
 while (res->next()) {
  records.push_back(new T(res));
 }

 // No need to worry about RVO
}

现在在你的主目录中:

Query::ResultType results; // not a pointer!

然后你可以调用每个类型,例如

getQuery().run<DifferentDerivedResult>(results);

如果您想避免 BaseResult,这会对您的设计进行最小的更改。完全键入您可以模板化所有内容 - 但我不确定什么功能 BaseResult正在给你,这是否可能..

关于c++ - 如何使用模板和继承来更正和改进此 C++ 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4439194/

相关文章:

c# - 使用存储过程的命令模式

java - 将对象转换为字节/从字节转换的设计模式

javascript - JSON 在我的 JavaScript 中被全局修改...为什么?

c++ - "Reparent"来自编译代码的类

c++ - 按值传递容器会使迭代器无效吗?

c++ - 带有红黑树的免费列表分配器

c++ - 返回值会被临时销毁吗?

c# - 如何使用 NHibernate 将责任模式映射到 SQL

c++ - 函数模板参数包的问题

C++17,为什么自动非类型模板参数不能与 SFINAE 一起使用