LINUX.ORG.RU

C++ вызов метода объекта в выражении с конструктором

 ,


0

2

Добрый день.
Подскажите пожалуйста момент.
Можно в C++ вызывать метод объекта сразу при создании:


class SomeClass {
public:
    int someMember() { return 0; }
};

int main() {

int i = SomeClass().someMember();

return 0;

}

Я так никогда не делал, т.к. считал, что это не по фэншую. Но вот иногда встречается в библиотеках эта форма (например в OpenCV есть).
Как вы к такому относитесь? И укажите пожалуйста, если в курсе, в стандарте такая форма где-то упомянается?

★★★★

А зачем это упоминать в стандарте? Это не какая-то специальная форма. Создание объекта, вызов метода. Главное не делать что-то вроде

auto p = std::string("Hello").c_str();

anonymous ()

Можно и это ничем не отличается, скажем, вот от такого:

void show_msg_length(const std::string & what) {
  std::cout << "length: " << what.size() << std::endl;
}

...
show_msg_length("Hello, World!");
show_msg_length("Bye, World!");
Временный объект, созданный при вызове show_msg_length будет автоматически уничтожен сразу по завершению выражения, в котором он создан.

eao197 ★★★★★ ()

Как вы к такому относитесь?

Нормально. Сам так делаю. Это же хорошо ограничивает время жизни объекта.

И укажите пожалуйста, если в курсе, в стандарте такая форма где-то упомянается?

Явно её нет необходимости упоминать. Создание объекта – выражение и работает так же как и вызов функции, возвращаюей объект, а дальше с ним можно делать что угодно.

xaizek ★★★★★ ()
Ответ на: комментарий от yoghurt

С виртуальными методами может быть неожиданность, только если вызывать их непосредственно из конструктора. К вопросу ТС это никакого отношения не имеет

Gvidon ★★★★ ()

Вполне нормальное использование.

std::thread( thread_function ).detach();

Главное помнить, что объект SomeClass() временный и будет уничтожен в конце выражения, поэтому нужно избегать выражений как в примере выше:

auto p = std::string("Hello").c_str();

это не по фэншую

Технарь должен объяснять все четко, ясно и техническими терминами (иначе, скорее всего, он сам не понимает что к чему). «Не по феншую» или «не комильфо» в техническом разговоре - признак балабола.

anonymous ()
Ответ на: комментарий от anonymous

Технарь должен объяснять все четко, ясно и техническими терминами (иначе, скорее всего, он сам не понимает что к чему). «Не по феншую» или «не комильфо» в техническом разговоре - признак балабола.

Не выпендривайся. Выражение «по фэншую ли это?» можно интерпретировать как «нарушает ли применение такой конструкции лаконичность, удобочитаемость, простоту кода?». Это достаточно простой вопрос. И если он у тебя вызывает ступор или непонимание, то спроси, что собеседник имеет ввиду, а не пиши поток сам знаешь чего в комментарии, специалист ты наш.

rumgot ★★★★ ()
Ответ на: комментарий от WitcherGeralt

Если тебе от класса нужен только один метод, то, скорее всего, класс и не нужен вовсе.

Это если класс мой. А если не мой. Скажем, начиная с C++11 не рекомендуется использовать std::rand. А если потребуется сгенерировать одно случайное число из заданного диапазона в C++11, то придется написать что-то вроде:

#include <random>
#include <iostream>

int main()
{
    using namespace std;
    mt19937 gen{random_device{}()};
    std::cout << uniform_int_distribution<>{350, 3500}(gen) << std::endl;
}
Где экземпляры random_device и uniform_int_distribution нужны только для вызова всего одного метода.

eao197 ★★★★★ ()

С точки зрения языка это совершенно нормально. С точки зрения архитектуры это зависит от того что реально происходит и может быть хорошим или плохим решением.

slovazap ★★★★★ ()
Ответ на: комментарий от rumgot

Выражение «по фэншую ли это?» можно интерпретировать

В том и суть, что это выражение можно интерпретировать очень широко и каждый понимает его по-своему. Ну, а самые упертые бараны будут всех убеждать, что их понимание самое правильное.

Это достаточно простой вопрос.

Термин «простой вопрос» - признак манипулятора.

И если он у тебя вызывает ступор или непонимание

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

P.S. Крепко же тебя зацепило. С чего бы это?

anonymous ()
Ответ на: комментарий от anonymous

это он должен уточнять, что именно ты хочешь

От тебя я ничего не хочу. Я не считаю тебя достойным давать советы. Все кто хотел все поняли. Иди гуляй.

rumgot ★★★★ ()
Ответ на: комментарий от eao197

придется написать

Невелика разница

std::mt19937 gen {std::random_device {}()};
std::cout << std::uniform_int_distribution<> {350, 3500}(gen) << std::endl;
std::srand(std::time(0));
std::cout << std::rand() % (3500 - 350) + 350 << std::endl;

А использовать uniform_int_distribution, чтобы сгенерировать одно случайное число, никто не рекомендует

Rot1 ()
Последнее исправление: Rot1 (всего исправлений: 2)
Ответ на: комментарий от Rot1

Если доколупываться до столба, то тогда уж так:

std::srand(static_cast<unsigned int>(std::time(nullptr)));
std::cout << std::rand() % (3500 - 350) + 350 << std::endl;
чтобы нормальные компиляторы предупреждениями не сыпали.

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

error: no member named ‘time’ in namespace ‘std’; did you mean simply ‘time’

Ну и имхо порно же, да и не все предупреждения одинаково полезны (где кстати nullptr != 0? Офигительные истории вообще).

srand((unsigned)time(nullptr));
std::cout << rand() % (3500 - 350) + 350 << std::endl;
anonymous ()
Ответ на: комментарий от anonymous

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

error: no member named ‘time’ in namespace ‘std’; did you mean simply ‘time’

Не мешало бы подучить матчасть и открыть для себя #include <ctime>

Ну и имхо порно же, да и не все предупреждения одинаково полезны (где кстати nullptr != 0? Офигительные истории вообще).

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

А так возьмите свежие версии clang-а (ну как свежие, с версии 5.0) и попробуйте скомпилировать вот этот код с ключиками -Weverything и -Wno-c++98-compat:

#include <random>
#include <iostream>
#include <ctime>

int
main()
{
    std::srand((unsigned)(std::time(0)));
    std::cout << std::rand() % (3500 - 350) + 350 << std::endl;
}

Откроете для себя мир удивительных историй.

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

А ты думаешь чем я собирал?

-Weverything

Не рекомендуется разработчиками для реального использования (но я тоже его использую, тем не менее не забывая про это).

Про какую адекватность после этого ты будешь говорить, да ещё и накатав пост с нулём информации а только с булькотанием в лужу?

anonymous ()
Ответ на: комментарий от anonymous

Про какую адекватность после этого ты будешь говорить

Про отсутствующую у вас. Ибо как можно сперва спотыкаться вот об это:

error: no member named ‘time’ in namespace ‘std’; did you mean simply ‘time’

а потом еще рассчитывать что вас будут воспринимать всерьез... Мне не понятно.

eao197 ★★★★★ ()
Ответ на: комментарий от eao197

Эти функции лежат в глобальном неймспейсе, и обращаться к ним через std:: не имеет особого смысла.

В данном куске кода они включены неявно рекурсивно через <iostream>. А обращение через std:: начинает работать только когда явно включить <random> и <ctime>.

Зачем бестолковая лишняя писанина?

anonymous ()