【问题标题】:How to correct and improve this c++ code using templates and inheritance?如何使用模板和继承来纠正和改进这个 c++ 代码?
【发布时间】:2010-12-14 12:34:42
【问题描述】:

我正在学习 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);
}

【问题讨论】:

    标签: c++ design-patterns templates inheritance


    【解决方案1】:

    首先,你的作业不正确

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

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

    我会对您的代码进行一些更改,首先,必须在任何地方使用 vector&lt;...&gt; 会导致 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 为您提供什么功能以及这是否可能..

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多