Есть ли проблемы в использовании Статической функции-члена для инициализации переменной-константы в списке инициализаторов? - PullRequest
0 голосов
/ 07 февраля 2019

Я хочу, чтобы в моей программе был класс, который напрямую принимает аргументы командной строки из метода main.Я хочу, чтобы часть этой информации была константой классу, но также зависела от введенных аргументов командной строки.

Я прочитал подробный ответ здесь: C ++ определение постоянной переменной-члена внутри классаконструктор , но я все еще немного сбит с толку ...

main.cpp:

#include "Launcher.h"

int main(int argc, char *argv[]) {
    Launcher launcher(argc, argv);

    // do other stuff with launcher

    return 0;
}

Launcher.h:

#ifndef LAUNCHER_H
#define LAUNCHER_H

#include <string>
#include <vector>

class Launcher {
public:
    Launcher(int, char *[]);

private:
    const int argumentCount;
    const std::vector<std::string> arguments;

    static const std::vector<std::string> INIT_arguments(int, char *[]);
};

#endif

Launcher.cpp

#include "Launcher.h"

Launcher::Launcher(int inputCount, char *inputArguments[]) :
    argumentCount(inputCount),
    arguments(INIT_arguments(inputCount, inputArguments))
{}

Launcher::INIT_arguments(int inputCount, char *inputArguments[]) {
    std::vector<std::string> argumentVector;
    for (int i = 0; i < inputCount; i++) {
        std::string currentArgument = inputArguments[i];
        argumentVector.push_back(currentArgument);
    }
    return argumentVector;
}

(Я понимаю, что в этом примере могут быть альтернативные методы для достижения тех же результатов без использования списков инициализатора. В других случаях я использовал сложные функции для определения значения переменной const, но выбралэтот простой пример для демонстрации концепции.)

Мои вопросы:

  1. Есть ли проблемы с инициализацией переменной-члена const с помощью статической функции (в приведенном выше примере)?
  2. Что-то меняется / есть ли еще проблемы, если функция, используемая для инициализации переменной const, нестатична?
  3. Есть ли какие-либо различия?разница между определением функции в заголовочном файле вместе с ее объявлением по сравнению с тем, как она была объявлена ​​в заголовочном файле, а затем определена в исходном файле?Есть ли различия, если он статический / нестатический?
  4. Не имеет отношения к общему вопросу, но ... Есть ли простой способ передать переменную char * [] по ссылке или, возможно, более эффективный способ?

1 Ответ

0 голосов
/ 07 февраля 2019

Есть ли проблемы с инициализацией переменной-члена const с помощью статической функции (в примере выше)?

Нет.Можно утверждать, что такая локальная вспомогательная функция, которая имеет мало общего с вашим реальным классом, могла бы вместо этого быть передана на аутсорсинг в вспомогательную / служебную сущность, возможно, свободную функцию (шаблон) в анонимном пространстве имен или где-то еще (чтобы сделать ее тестируемой).

Что-нибудь изменится / есть ли еще проблемы, если функция, используемая для инициализации переменной const, нестатична?

Делая ее static, гарантирует, что членФункция не имеет ничего общего с состоянием экземпляров (очевидно, то же самое для свободных функций).Я бы определенно сохранил это для функций, которые используются для инициализации состояния.

Есть ли разница между определением функции в заголовочном файле вместе с ее объявлением и тем, как оно было объявлено в заголовочном файле?определен в исходном файле?

Нет.Однако если вы сделаете эту функцию бесплатной, вам нужно позаботиться о возможных нарушениях ODR и, по крайней мере, пометить ее как inline.

Есть ли простой способ передать символ * [] переменная по ссылке или, возможно, более эффективный способ?

Существует более эффективный способ, т. е. вообще не использовать функцию и полагаться на конструктор std::vector (перегрузка # 4), которая принимает два итератора в качестве аргумента.Указатели на один и тот же необработанный массив здесь хороши, так что вы можете просто сделать:

Launcher::Launcher(int inputCount, char *inputArguments[]) :
   argumentCount(inputCount),
   arguments(inputArguments, inputArguments + inputCount) {}

Обратите внимание, что Launcher, похоже, не предназначен для изменения аргументов командной строки.В этом случае вам не нужно копировать строки вообще.Вместо этого используйте std::string_view (если доступен C ++ 17) или просто оставьте его как const char* (одна приятная вещь в аргументах командной строки - вам не нужно думать об их времени жизни).

...