Здравствуйте, попался такой пример.
Проверил и на MSVC, и на g++, пример компилируется, но работает не так, как ожидал.
Дело в том, что не вызывается ни конструктор, ни деструктор.
Скажите, пожалуйста, в чём ошибка?
#include <iostream>
class MyClass {
static unsigned counter;
public:
MyClass() {
++counter;
std::cout << "MyClass(), counter = " << counter << std::endl;
}
MyClass(const MyClass&) {
++counter;
std::cout << "MyClass( const MyClass& ), counter = " << counter << std::endl;
}
~MyClass() {
std::cout << "~MyClass()" << std::endl;
}
};
unsigned MyClass::counter = 0;
int main()
{
MyClass mc( MyClass() ); // здесь ничего не вызывается
// MyClass x; // а здесь всё равботает так, как ожидалось
// MyClass y( x ); // и здесь работает
return 0;
}
Здравствуйте, plusovik, Вы писали:
P>Здравствуйте, попался такой пример. P>Проверил и на MSVC, и на g++, пример компилируется, но работает не так, как ожидал. P>Дело в том, что не вызывается ни конструктор, ни деструктор. P>Скажите, пожалуйста, в чём ошибка?
P> MyClass mc( MyClass() ); // здесь ничего не вызывается
Потому что это не создание переменной, а declaration функции mc. Особенность c++
_____________________
С уважением,
Stanislav V. Zudin
Здравствуйте, plusovik, Вы писали:
P>Здравствуйте, попался такой пример. P>Проверил и на MSVC, и на g++, пример компилируется, но работает не так, как ожидал. P>Дело в том, что не вызывается ни конструктор, ни деструктор. P>Скажите, пожалуйста, в чём ошибка?
А ты варнинги не читаешь, да?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Stanislav V. Zudin, Вы писали: P>> MyClass mc( MyClass() ); // здесь ничего не вызывается SVZ>Потому что это не создание переменной, а declaration функции mc. Особенность c++
Спасибо за ответ, почти разобрался:
компилятор подумал, что mc — это объявление функции, принимающей в качестве аргумента объект MyClass и возвращающей
также объект MyClass.
А скобки у аргумента MyClass() почему не вызвали у компилятора подозрений?
В качестве чего он их воспринял?
Здравствуйте, T4r4sB, Вы писали: P>>и возвращающей также объект MyClass. TB>Неверно. TB>Посмотри ты уже в варнинги наконец
Ты можешь сказать, что именно неверно? Какой тогда объект возвращает функция?
Warning выдаёт только clang, остальные молчат.
warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
Здравствуйте, plusovik, Вы писали:
P>Здравствуйте, Stanislav V. Zudin, Вы писали: P>>> MyClass mc( MyClass() ); // здесь ничего не вызывается SVZ>>Потому что это не создание переменной, а declaration функции mc. Особенность c++
P>Спасибо за ответ, почти разобрался: P>компилятор подумал, что mc — это объявление функции, принимающей в качестве аргумента объект MyClass и возвращающей P>также объект MyClass.
P>А скобки у аргумента MyClass() почему не вызвали у компилятора подозрений? P>В качестве чего он их воспринял?
давай чуть по другомк запишем, думаю станет понятно без дополнительных объяснений
#include <iostream>
class MyClass {
static unsigned counter;
public:
MyClass() {
++counter;
std::cout << "MyClass(), counter = " << counter << std::endl;
}
MyClass(const MyClass&) {
++counter;
std::cout << "MyClass( const MyClass& ), counter = " << counter << std::endl;
}
~MyClass() {
std::cout << "~MyClass()" << std::endl;
}
};
unsigned MyClass::counter = 0;
int main()
{
MyClass mc( MyClass f() ); // mc это функция, принимающая аргументом функцию f
MyClass f();
mc(f);
// MyClass x; // а здесь всё равботает так, как ожидалось
// MyClass y( x ); // и здесь работаетreturn 0;
}
MyClass f()
{
MyClass x;
return x;
}
MyClass mc( MyClass f() )
{
MyClass x = f();
return x;
}
MyClass mc( MyClass() );
// функция mc, принимает в качестве аргумента указатель на другую функцию, которая без аргументов
// и функция mc, и её аргумент возвращают объект MyClass
// а аргумент функции mc без имени, поэтому и показался конструктором
// в конструкторе MyClass(const MyClass&) аргумент также без имени, потому что им не пользовались
Здравствуйте, plusovik, Вы писали:
P>Здравствуйте, Stanislav V. Zudin, Вы писали: P>>> MyClass mc( MyClass() ); // здесь ничего не вызывается SVZ>>Потому что это не создание переменной, а declaration функции mc. Особенность c++
P>Спасибо за ответ, почти разобрался: P>компилятор подумал, что mc — это объявление функции, принимающей в качестве аргумента объект MyClass и возвращающей P>также объект MyClass.
Нет.
Компилятор подумал, что это — это объявление функции `mc`, принимающей в качестве [неименованного] параметра функцию `MyClass (void)` и возвращающую объект типа `MyClass`. Если добавить имя для параметра, то получится
MyClass mc( MyClass fun() );
а так параметр типа "функция" эквивалентен параметру типа "указатель на функцию", то есть ваше объявление фактически эквивалентно
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>Компилятор подумал, что это — это объявление функции `mc`, принимающей в качестве [неименованного] параметра функцию `MyClass (void)` и возвращающую объект типа `MyClass`. Если добавить имя для параметра, то получится
Спасибо, понял.
А почему компилятор в первую очередь действует так, будто это декларация функции, а не инициализация нового объекта?
По каким словам гуглить и что читать?
P>Спасибо, понял. P>А почему компилятор в первую очередь действует так, будто это декларация функции, а не инициализация нового объекта? P>По каким словам гуглить и что читать?