Бесконечный цикл в конструкторе без for или while
Я сделал тест здесь, но выход-это цикл без конца, я не знаю, почему.
на самом деле, я делаю еще один тест, но когда я написал это, я не понимаю, как цикл произошел. Выводится" ABC " многократно.
#include <map>
#include <string>
#include <iostream>
class test
{
public:
std::map <int, int> _b;
test();
test (std::map<int, int> & im);
~test();
};
test::test()
{
std::cout<<"abc";
_b.clear();
_b[1]=1;
test(_b);
}
test::test(std::map <int, int>& im)
{
std::cout<<im[1];
}
test::~test() {};
int main ()
{
test a;
}
4 ответов:
проблема здесь в том, что компилятор интерпретирует
test(_b);не как код, который создает временный объект типа
testпередача параметра_b, а как объявление переменной для переменной_bтипаtest, используя конструктор по умолчанию. Следовательно, то, что выглядит как кусок кода, который создает временныйtestобъект, использующий второй конструктор, вместо этого рекурсивно создает новый объект типаtestи вызов конструктора другой раз.чтобы исправить это, вы можете дать переменной явное имя, например
test t(_b);это можно интерпретировать только как переменную типа
testимениtинициализируется с помощью второго конструктора.я никогда видел это раньше, и я уже много лет программирую на C++. Спасибо, что показали мне еще один угловой случай языка!
для официального объяснения: согласно к спецификации ISO C++03, §6.8:
существует неоднозначность в грамматике, включающей выражения-операторы и объявления: выражение-оператор с явным преобразованием типа в стиле функции (5.2.3), поскольку его крайнее левое подвыражение может быть неотличимо от объявления, где первый Декларатор начинается с (. в этих случаях заявление, декларация.
(Курсив мой). Другими словами, в любое время c++ может интерпретировать оператор как выражение (временное приведение объекта) или как объявление (переменной), он выберет объявление. Спецификация C++ явно дает
T (a);
в качестве примера объявления, а не приведения
aчто-то типаT.это C++ ' s Самый Досадный Разбор - то, что выглядит как выражение, вместо этого интерпретируется как объявление. Я видел MVP раньше, но я никогда не видел его в этом контексте.
надеюсь, что это помогает!
проблема в том, что из конструктора вы снова вызываете тест contructor (_b)
test:: test(){std:: cout
вот что происходит
каждый раз, когда вы вызываете test(_b), он сначала вызывает конструктор по умолчанию test::test, и он по очереди вызывает тест (_b), и цикл продолжается и продолжается до тех пор, пока стек не переполнится.
удалить тест(_b) из конструктора по умолчанию
Я уверен, что вы на самом деле не "вызове конструктора" поскольку они не являются непосредственно вызываемыми IIRC. Законники имели дело с конструкторами не будучи имени функции - у меня нет копии стандарта под рукой, или я мог бы процитировать его. Я верю, что вы делаете с
test(_b)создаетбезымянныйвременный, который снова вызывает конструктор по умолчанию.
Я не знаком с особенностями стандарта, но может быть, что вызов конструктора в конструкторе не определен. Как таковой он может быть зависимым от компилятора. В этом конкретном случае он вызывает бесконечную рекурсию вашего конструктора по умолчанию, никогда не вызывая ваш конструктор с аргументом map.
C++ FAQ 10.3 имеет пример с конструктором, который имеет два параметра. Если вы добавляете параметры int во второй конструктор, например
test(map, int), Это проявляет несколько нормальное поведение.для хорошей формы я бы просто изменил
test::test(std::map <int, int>& im)наtest::testInit(std::map <int, int>& im)иtest(_b)доtestInit(_b).
Comments