class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
Может ли первый конструктор назвать второй?Может ли конструктор вызвать другой конструктор в C++?
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
Может ли первый конструктор назвать второй?Может ли конструктор вызвать другой конструктор в C++?
Не before C++11.
Извлечь общую функциональность в отдельную функцию. Обычно я называю эту функцию construct().
«Так называемый» второй вызов будет скомпилирован, но имеет другое значение в C++: он создаст новый объект, временный, который затем будет немедленно удален в конце инструкции. Итак, нет.
Деструктор, однако, можно назвать без проблем.
+1 - и 'construct()' - хорошее имя. – peterchen
+1 - и вы должны добавить, что можно будет вызвать конструкторы из конструкторов в том же классе в следующей версии C++ (C++ 0x). См. Http://www2.research.att.com/~bs/C++0xFAQ.html#delegating-ctor – Klaim
Можете ли вы привести пример функции construct()? Я знаю, что это довольно просто, но я думаю, что люди сочтут это полезным. – MattClimbs
Не раньше C++0x
, no.
НО, только из академического интереса я придумал действительно ужасным способом *, чтобы сделать это с помощью оператора размещения «новый» (кто-то забота, чтобы указать, как портативный это?)
#include <new>
#include <iostream>
class A
{
public:
A(int i, int j)
: i_(i), j_(j) { }
A(int i)
{ new (this) A(i, 13); }
int i_,j_;
};
int
main() {
A a1(10,11), a2(10);
std::cout
<< a1.i_ << ", "
<< a1.j_ << std::endl
<< a2.i_ << ", "
<< a2.j_ << std::endl;
return 0;
}
* Ад нет, я не пишу это в производственном коде.
Я думаю, что это довольно портативно; place-new находится в стандарте ISO C++. «Другие использования, однако, включают вызов конструктора напрямую, то, что не разрешает другой язык C++». Из Википедии: http://ru.wikipedia.org/wiki/Placement_syntax – haavee
Что произойдет, если A происходит от класса B? Будет вызываться конструктор B, а затем A, который затем вызовет новый A '(другой конструктор A) и перезапишет все, что уже сделано B, а затем снова вызовет B, затем A'. Вывод: если B делает что-то значимое (т. Е. Выделяет ресурс), это нарушит код (т. Е. Спровоцирует утечку ресурса). – paercebal
@paercebal да, это также не сработает, если A - абстрактный класс. –
Ответ на самом деле «да», но, как предложили другие, он не делает то, что вы хотите. Вы можете, конечно, использовать конструктор базового класса неявно или явно:
struct B {
B() {}
B(int x) {}
};
struct A : public B {
A() {} // calls B() implicitly
A(int a, int b) : B(b) {} // calls B(int) explicitly
};
Не напрямую. Есть несколько способов обойти это.
Из списка инициализаторов конструктора вашего класса вы можете вызвать конструктор для любого базового класса и всех переменных-членов.
Таким образом, вы можете реорганизовать свой класс и разделить его на несколько меньших, чтобы решить эту проблему. Обычно исполняемый код может быть помещен в объект-член или, возможно, в базовый класс. Затем каждый из конструкторов основного класса должен решить, какой конструктор использовать для инициализации этого элемента.
class B {
B() { }
B(int b) { DoSomething(); }
}
class A{
A(int a = 5) : b(a) { } // call B's constructor which does something
A() : b() {} // call B's constructor which does nothing
B b;
};
Это старый вопрос; Однако
class A{
A(int a = 5){
DoSomething();
A();
}
A(){...}
}
может быть
class A{
A(int a = 5){
*this = A();
DoSomething();
}
A(){...}
}
Я думаю, что назначение '* this = A();' будет использовать конструктор копии по умолчанию (если вы его не определили), который может быть не таким, каким вы хотите? – austinmarton
Похожий вопрос здесь: https: // Http: //stackoverflow.com/questions/308276/c-call-constructor-from-constructor –