Сценарий: у меня есть функция, которая вызывает параметризованный конструктор, когда я хочу инициализировать. Поэтому я хочу вызывать конструктор по своему выбору, когда захочу. Но это работает, когда я использую A()
вызвать конструктор по умолчанию, но он не работает с конструктором с параметром, а я получаю следующую ошибку.
Ошибка 1 ошибка C2082: переопределение формального параметра
‘tmp’ c: \ users \ adnan \ Documents \ visual studio
2012 \ projects \ project3 \ project3 \ source.cpp 12 1 Project3
class A
{
public:
int id;
void i(int tmp)
{
A(tmp);
}
A()
{
cout<<"default const"<<endl;
}
A(int id)
{
this->id = id;
}
};
int main()
{
A obj[2];
for(int i=0;i<2;i++)
{
obj[i].i(i*2);
}
cout<<"obj[0].id = "<<obj[0].id;
cout<<endl;
cout<<"obj[1].id = "<<obj[1].id;
cout<<endl;system("pause");
return 0;
}
В вашей функции члена i
ты пытаешься позвонить A
как это:
void i(int tmp)
{
A(tmp);
}
по факту A(tmp)
объявляет переменную tmp
типа A
, поскольку tmp
уже объявлен как int
внутри той же области компилятор жалуется.
Если вы хотите переменную типа A
и инициализировать его через A::A(int)
Тогда вам нужно дать имя этой переменной. Например.:
A a(tmp);
Линия
A(tmp);
не вызывает конструктор, он объявляет экземпляр A
называется «ТМП» — это эквивалентно
A tmp;
Поскольку формальный параметр называется «tmp», это переопределение.
(Несмотря на то, что вы могли ожидать, A tmp();
является не эквивалентно A tmp;
— ищите «самый неприятный анализ», чтобы узнать больше.)
Причина, по которой он «работает», когда вы пишете
A();
является то, что он создает анонимный экземпляр (совершенно другой this
) который сразу выбрасывается
Другими словами, этот код не делает то, о чем вы думали.
В C ++ 03 нет способа явно вызвать конструктор, кроме как с помощью «размещения нового», что нельзя делать, если вы не знаете, что делаете.
Если вы хотите отложить «инициализацию» объекта до того, как он будет построен, используйте функцию инициализации:
class A
{
public:
int id;
void init(int tmp)
{
id = tmp;
}
A()
{
cout<<"default const"<<endl;
init(0); // Avoid accidental undefined behaviour.
}
A(int id)
{
init(id);
}
};
В грамматике существует двусмысленность, связанная с выражениями-выражениями
и декларации:
Я процитировал Стандарт C ++.
Что в этом фрагменте кода
void i(int tmp)
{
A(tmp);
}
А (TMP); рассматривается компилятором как объявление, эквивалентное
A tmp;
Чтобы отличить вызов конструктора от объявления, вы можете написать
void i(int tmp)
{
( A )( tmp );
}
В этом случае (A) (tmp) является вызовом конструктора, хотя в этом утверждении нет никакого смысла.