Nano Hash - криптовалюты, майнинг, программирование

Список инициализаторов конструктора С++ со сложными назначениями

Предположим, я хочу иметь конструктор, который получает некоторые параметры, и с этими параметрами я могу вычислить значения для его переменных-членов. За исключением того, что значения переменных-членов не являются простыми присвоениями параметров. Они требуют создания других объектов и преобразования значений, прежде чем их можно будет использовать в качестве значений для переменных-членов.

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

Другой вариант — не использовать список инициализаторов и позволить вызвать конструктор по умолчанию, а затем перезаписать значения внутри конструктора аккуратными вычислениями.

А что если у класса нет конструктора по умолчанию? Как можно сделать это аккуратно?

/* a class without a default constructor */
class A {
  public:
    B x1
    B x2
    A(B x1_, B x2_) : x1{x1_}, x2{x2_} {};
};

/* a class that contains an A object and needs to initialize it based on some complex logic */
class C {
  public:
    A a;
    C(D d) :
      a{b1,b2} // ultimately I just want to initialize a with two B objects
               // but unfortunatelly they require a lot of work to initialize
               // including instantiating other objects and using tons of methods
      {}
};

Ответы:


1

Как насчет добавления некоторых методов статического преобразования?

class C {
  private:
    static B transform1(D&);
    static B transform2(D&);
  public:
    A a;
    C(D d) :
      a{transform1(d),transform2(d)}
      {}
};

Связанный:

08.11.2013
  • не на 100% доволен этим решением, но оно определенно самое чистое. 25.11.2013

  • 2

    В этом случае я бы использовал указатели. Вот модифицированная версия вашего примера:

    //Class A is not modified
    /* a class without a default constructor */
    class A {
      public:
        B x1
        B x2
        A(B x1_, B x2_) : x1{x1_}, x2{x2_} {};
    };
    
    
    
    /* a class that contains an A object and needs to initialize it based on some complex logic */
    class C {
      public:
        A* a;   // I declare this as a pointer
        C(D d)
          {
              // Perform all the work and create b1,b2
              a = new A(b1, b2);
          }
    
        ~C()    // Create a destructor for clean-up
        {
              delete a;
        }
    
    };
    

    Используя новый оператор, я могу инициализировать объект, когда захочу. И так как объект находится в области класса, я удаляю его в деструкторе (в конце области видимости класса)

    08.11.2013

    3

    Я бы предложил другое более понятное решение, создать статический метод в классе A со всей сложной логикой построения.

    class A {
    public:
       B x1
       B x2
       A(B x1_, B x2_) : x1{x1_}, x2{x2_} {};
    
       static A FromD(D d) {
           B b1, b2;
           /* Some complex logic filling b1 and b2 */
           return A(b1, b2);
       }
    };
    
    class C {
    public:
        A a;
        C(D d) :
          a(A::FromD(d))
        {}
    };
    

    Обратите внимание, что в этом решении используется неявно определенный конструктор перемещения, поэтому не забудьте пересмотреть свою ситуацию и проверить, нужно ли вам определять его явно в соответствии с правило пяти

    23.12.2019
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..