инициализировать переменную в конструкторе
От: sergey2b ЮАР  
Дата: 12.03.25 20:05
Оценка: :)
Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе

class Viewer {
public:
Viewer(std::string suffix):
kWindowName_(suffix.empty() ? kWindowName_ : kWindowName_ + " " + suffix){};
private:
const std::string kWindowName_{"Video Viewer"};
};

данный код генерирует ошибку error G99FBF662: field 'kWindowName_' is uninitialized when used here
Re: инициализировать переменную в конструкторе
От: bnk СССР http://unmanagedvisio.com/
Дата: 12.03.25 20:16
Оценка: 9 (1)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе


S>class Viewer {

S>public:
S>Viewer(std::string suffix):
S> kWindowName_(suffix.empty() ? kWindowName_ : kWindowName_ + " " + suffix){};
S>private:
S> const std::string kWindowName_{"Video Viewer"};
S>};

S>данный код генерирует ошибку error G99FBF662: field 'kWindowName_' is uninitialized when used here


Так не пойдет?

class Viewer {
  public:
    Viewer(std::string suffix):
      kWindowName_(suffix.empty() ? "Video Viewer" : "Video Viewer " + suffix){};
  private:
    const std::string kWindowName_;
};
Re: инициализировать переменную в конструкторе
От: T4r4sB Россия  
Дата: 12.03.25 20:27
Оценка: 9 (1)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе


class Viewer {
public:
Viewer(std::string_view suffix) {
  if (!suffix.empty()) {
    kWindowName_ += ' ';
    kWindowName_ += suffix;    
  }
}
private:
 const std::string kWindowName_{"Video Viewer"};
};
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: инициализировать переменную в конструкторе
От: xma  
Дата: 12.03.25 21:42
Оценка: 9 (1)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе


40 лет как под наркозом
я работал говновозом говнокодером


S>данный код генерирует ошибку error G99FBF662: field 'kWindowName_' is uninitialized when used here


гуглим "инициализация константы в конструкторе класса c++", находим

Конструкторы и инициализация объектов
https://metanit.com/cpp/tutorial/5.2.php

делаем выводы (навскидку должно получится что то такое)

  топорный вариант
class Viewer {

private:
const std::string kWindowName_;

public:
Viewer(std::string suffix):
kWindowName_(suffix.empty() ? "Video Viewer" : "Video Viewer" + " " + suffix){};

};


ну и варианты с оптимизацией универсальности (не гарантирую что работают, проверять лень) :

  с uniform-инициализацией (C++11)
class Viewer {

private:
const std::string kWindowName_Base{"Video Viewer"};
const std::string kWindowName_;

public:
Viewer(std::string suffix):
kWindowName_(suffix.empty() ? kWindowName_Base : kWindowName_Base + " " + suffix){};

};


если не заводится, можно по пробывать так

  с инициализацией в конструкторе
class Viewer {

private:
const std::string kWindowName_Base;
const std::string kWindowName_;

public:
Viewer(std::string suffix):
kWindowName_Base("Video Viewer"), 
kWindowName_(suffix.empty() ? kWindowName_Base : kWindowName_Base + " " + suffix){};

};


P.S.:

если что то не работает, то гугл и отладка в помощь
Отредактировано 12.03.2025 21:48 xma . Предыдущая версия .
Re[2]: инициализировать переменную в конструкторе
От: xma  
Дата: 12.03.25 21:45
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Viewer(std::string_view suffix) {

TB> kWindowName_ += suffix;
TB>}
TB> const std::string kWindowName_{"Video Viewer"};

это же константа, как ты её в теле конструктора изменишь — её либо сразу, либо в списке инициализации конструктора только можно задать
Отредактировано 12.03.2025 21:47 xma . Предыдущая версия .
Re[3]: инициализировать переменную в конструкторе
От: T4r4sB Россия  
Дата: 13.03.25 06:15
Оценка:
Здравствуйте, xma, Вы писали:

xma>это же константа, как ты её в теле конструктора изменишь — её либо сразу, либо в списке инициализации конструктора только можно задать


А, точно.
Тогда твой вариант так наверное лучше
class Viewer {

private:
  static const std::string kWindowName_Base{"Video Viewer"};
  const std::string kWindowName_;

public:
  Viewer(std::string_view suffix):
  kWindowName_(suffix.empty() ? kWindowName_Base : kWindowName_Base + " " + suffix){};

};


добавил статик чтоб не хранить лишний элемент, и добавил стрингвью чтоб суффикс попусту не копировать туда сюда
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[4]: инициализировать переменную в конструкторе
От: xma  
Дата: 13.03.25 11:49
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>добавил статик чтоб не хранить лишний элемент


а точно ли так можно ? а то в старых стандартах C++ статические константные строки нельзя было инициализировать прямо в классе только за его пределами
Re[5]: инициализировать переменную в конструкторе
От: T4r4sB Россия  
Дата: 13.03.25 12:02
Оценка:
Здравствуйте, xma, Вы писали:

xma>Здравствуйте, T4r4sB, Вы писали:


TB>>добавил статик чтоб не хранить лишний элемент


xma>а точно ли так можно ? а то в старых стандартах C++ статические константные строки нельзя было инициализировать прямо в классе только за его пределами


Набирал в браузере, а так нельзя, да
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re: инициализировать переменную в конструкторе
От: Videoman Россия https://hts.tv/
Дата: 13.03.25 13:32
Оценка: 9 (1)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе


Непонятно какая версия С++

class Viewer {

private:
const std::string kWindowName_;

public:
Viewer(std::string suffix) :
kWindowName_(std::string("Video Viewer") + (suffix.empty() ? "" : " " + suffix)){};

};
Re: инициализировать переменную в конструкторе
От: B0FEE664  
Дата: 13.03.25 17:53
Оценка: 9 (1) -1 :))) :)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе

есть

class Viewer 
{
  public:
    Viewer() = default;
    Viewer(std::string suffix): kWindowName_(Viewer().kWindowName_ + (suffix.empty() ? suffix  : ' ' + suffix)){};
  private:
    const std::string kWindowName_{"Video Viewer"};
};

  Скрытый текст
И каждый день — без права на ошибку...
Re: инициализировать переменную в конструкторе
От: Кодт Россия  
Дата: 13.03.25 18:48
Оценка: 19 (3) +1
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе


Самый простой и чистый способ — это разнести труъ константу "дефолтное значение" и рантайм-константное поле.
И вынести код конструирования значения в функцию, для удобства.

class Viewer {
private:
  static constexpr std::string_view kDefaultWindowName = "Video Viewer";
  static std::string make_window_name(std::string_view suffix) {
    std::string name{kDefaultWindowName};
    if (!suffix.empty()) { name += " "; name += suffix; }
    return name;
  }

  const std::string kWindowName = make_window_name("");  // для единообразия будем инициализировать поле так же, как в конструкторе

public:
  V(std::string_view suffix) : kWindowName{make_window_name(suffix)} { ..... }

  V() { ..... }  // дефолтная инициализация поля - и какая-то копипаста тела конструктора с вариациями

  V(SpecialTagAhaha) : V("special suffix ahaha") {}  // ну или повторное использование самого универсального конструктора, который все поля руками настроил
};
Перекуём баги на фичи!
Re[2]: инициализировать переменную в конструкторе
От: B0FEE664  
Дата: 14.03.25 17:29
Оценка: -1 :)
Здравствуйте, Кодт, Вы писали:

К>Самый простой и чистый способ — это разнести труъ константу "дефолтное значение" и рантайм-константное поле.


Стоит отметить, что делать константы приватными смысла нет.
И каждый день — без права на ошибку...
Re: инициализировать переменную в конструкторе
От: rg45 СССР  
Дата: 14.03.25 20:03
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста есть ли варианты инициализировать переменную в конструкторе


S>class Viewer {

S>public:
S>Viewer(std::string suffix):
S> kWindowName_(suffix.empty() ? kWindowName_ : kWindowName_ + " " + suffix){};
S>private:
S> const std::string kWindowName_{"Video Viewer"};
S>};

S>данный код генерирует ошибку error G99FBF662: field 'kWindowName_' is uninitialized when used here


Как вариант:

class Viewer {
public:
    Viewer() = default;
    explicit Viewer(const std::string& suffix)
        : kWindowName_(suffix.empty() ? defaultWindowName : defaultWindowName + " " + suffix){}

private:
    static constexpr std::string defaultWindowName = "Video Viewer";
    const std::string kWindowName_ = defaultWindowName;
};
--
Справедливость выше закона. А человечность выше справедливости.
Re[6]: инициализировать переменную в конструкторе
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 14.03.25 20:07
Оценка:
Здравствуйте, T4r4sB, Вы писали:


TB>>>добавил статик чтоб не хранить лишний элемент


xma>>а точно ли так можно ? а то в старых стандартах C++ статические константные строки нельзя было инициализировать прямо в классе только за его пределами


TB>Набирал в браузере, а так нельзя, да


Как же нельзя, когда можно?
Маньяк Робокряк колесит по городу
Re[3]: инициализировать переменную в конструкторе
От: Кодт Россия  
Дата: 17.03.25 11:56
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Стоит отметить, что делать константы приватными смысла нет.


А это уж на усмотрение.
Такая константа вполне может быть деталью реализации, на которую не следует закладываться извне.
Вот захотим переименовать окошко, или захотим прикрутить туда l10n/i18n, и всё, константа не константа. У ней поменяется время жизни, например. И уже нельзя будет просто так взять и обращаться на стадии before-main.
Но с другой стороны, захотим прибить гвоздями, сэкономить на спичках, дать гарантии загрузки динамических библиотек, — и сделаем её настоящей статической константой, а то и вовсе констэкспром (как я, собственно, и сделал для примера).
Перекуём баги на фичи!
Re[5]: инициализировать переменную в конструкторе
От: alsemm Россия  
Дата: 17.03.25 23:45
Оценка:
Здравствуйте, xma, Вы писали:

xma>а точно ли так можно ? а то в старых стандартах C++ статические константные строки нельзя было инициализировать прямо в классе только за его пределами

Помимо этого в старых версиях стандарта порядок инициализации модулей был неопределен (поменялось что-нибудь с тех пор?), поэтому можно получить красоту, когда конструктор Viewer вызовется до того как kWindowName_Base будет инициализирован.
Re[6]: инициализировать переменную в конструкторе
От: rg45 СССР  
Дата: 18.03.25 14:44
Оценка: +1
Здравствуйте, alsemm, Вы писали:

A>Помимо этого в старых версиях стандарта порядок инициализации модулей был неопределен (поменялось что-нибудь с тех пор?),


Всё так и осталось.

A>поэтому можно получить красоту, когда конструктор Viewer вызовется до того как kWindowName_Base будет инициализирован.


Да, но для этого зависимости между модулями нужно закрутить похитрее. Ну и чтобы налететь на эту проблему, у константы должно быть внутреннее связывание, всё-таки наверное. Что-то типа такого: http://rsdn.org/forum/cpp/3509539.1
Автор: rg45
Дата: 20.08.09
.

К счастью, сейчас константы std::string можно объявлять как constexpr, как вот здесь
Автор: rg45
Дата: 14.03 23:03
. Это исключает данную проблему в коде любой сложности.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 18.03.2025 14:55 rg45 . Предыдущая версия . Еще …
Отредактировано 18.03.2025 14:51 rg45 . Предыдущая версия .
Отредактировано 18.03.2025 14:50 rg45 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.