2016-08-04 11 views
0

Betrachten Sie diese Funktion:Kopieren boost :: program_options :: parsed_options

po::parsed_options ParserClass::parseOptions(int argc, char *argv[]) { 
    return po::command_line_parser(argc, argv) 
      .options(desc) 
      .positional(pos) 
      .run(); 
} 

desc und pos Membervariablen von ParserClass sind.

Ist diese Funktion sicher oder gibt sie ein parsed_options Objekt zurück, das Zeiger auf freigegebenen freien Speicher hat, weil der zugewiesene Speicher des ursprünglichen Objekts freigegeben wird, wenn die Funktion zurückgibt?

Wie können Sie die Semantik kennen? Ich habe versucht, den Quellcode zu lesen, um es herauszufinden, aber es war ein wenig kryptisch für mich. Die Dokumentation scheint nicht zu sagen.

Wenn die Funktion nicht sicher ist, wie könnte sie behoben werden? Sollten Sie die Klasse erweitern und einen Verschiebevorgang definieren?

Antwort

2

Wenn das Objekt kopiert oder verschoben werden, kann es bedeuten, grundsätzlich drei Dinge:

  1. Die Operationen sind gut definiert und verhalten sich sicher
  2. Bibliothek Autoren haben es vermasselt und Kopieren/Verschieben ist schlecht verhielten sich
  3. Sie müssen einige nicht offensichtliche Konventionen während der Verwendung befolgen (in der Regel aus Leistungsgründen).

Mit Boost (und so weit verbreiteten Teile davon als program_options) können wir zweite Option ausschließen und für die dritte möglicherweise die documentation konsultieren, um zu sehen, dass es nichts lächerlich ist.

Wenn Sie wirklich wollen wissen, dass argv Zeiger nicht die Funktion entweicht (ich denke, es ist der einzige verdächtige Ort da ist), können Sie überprüfen, ob die entsprechenden basic_command_line_parser Konstruktor kopiert sie in einen Vektor von std::string s (via detail::make_vector:)

template<class charT> 
basic_command_line_parser<charT>:: 
basic_command_line_parser(int argc, const charT* const argv[]) 
: detail::cmdline(
    // Explicit template arguments are required by gcc 3.3.1 
    // (at least mingw version), and do no harm on other compilers. 
    to_internal(detail::make_vector<charT, const charT* const*>(argv+1, argv+argc+!argc))), 
    m_desc() 
{}