2010-12-14 12 views
0

私はC++を学んでいて、やりたいことを大雑把に知っていますが、私はそれを間違ったやり方でやっています。とても疲れています。最善の方法は、このような何かをやっての(最初のすべての正しい方法)何:まずテンプレートと継承を使用してこの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); 
} 

答えて

1

、あなたの割り当ては

*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! 

次に、それぞれのt例えば、

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

これは、あなたのデザインに最小限の変更を導入して、あなたがBaseResultタイプを避けたかった場合は、完全にあなたはすべてのテンプレートができます - しかし、私はあなたを与えているものの機能BaseResultとこれが可能であるかどうかわからないんだけど...

関連する問題