我正在学习 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/