LINUX.ORG.RU

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

 ,


0

2

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


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

int main() {

int i = SomeClass().someMember();

return 0;

}

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

★★★★★

Последнее исправление: rumgot (всего исправлений: 1)

(std::ifstream){«crap»}.read(p,len);

anonymous
()

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

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 ★★★★
()
Ответ на: комментарий от Gvidon

К вопросу ТС это никакого отношения не имеет

Верно, вопрос ТС я прогнал глазами по диагонали, каюсь грешен

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

Это же хорошо ограничивает время жизни объекта

И намекает на то, что класс, точнее его инстанс, в том месте не требуется.

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

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

По-моему в C++ как раз все логично. Вот в Java проблемы, да.

anonymous
()

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

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 ★★★★★
()
Ответ на: комментарий от DELIRIUM

Точек следования нет начиная с C++11.

Да и они вообще тут не при чём.

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

За создание временного mt19937 каждый раз, когда нужно новое случайное число, в любом случае нужно бить по пальцам линейкой

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

Я же написал, что когда требуется единственное число.

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

Тогда его и сохранять в переменную не надо было.

Ошибка популярная, кстати.

anonymous
()

Паттерн билдер иногда так выглядит

auto inst = Builder(blabla).add(blabla).add(foo).add(bar).build();

или тип того. Вполне рабочий вариант и даже иногда «по-феншую»

ossa ★★
()
Последнее исправление: ossa (всего исправлений: 1)
Ответ на: комментарий от eao197

При желании, конечно, можно придумать случаи, когда это будет оправдано, но в реальности гораздо чаще будет встречаться что-то типа класса HelloWorld с методом print.

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

объект

Что здесь объект?

завершению выражения

Что здесь выражение?

anonymous
()

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

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

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

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

Ну и ещё

using std::cout,std::endl;
...
cout<< ... <<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
()
Ответ на: комментарий от eao197

тогда уж так std::rand() % (3500 - 350) + 350
eao197

сеньёр помидор знает что такая конструкция портит рандом?

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

сеньёр помидор знает что такая конструкция портит рандом?

Какие-то значения будут выпадать чуть реже.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.