Как перенаправить вызов перегруженного конструктора другому конструктору в C++/CLI
-
23-09-2019 - |
Вопрос
Я знаю, что нет возможности сделать это в чистый С++, но мне было интересно, можно ли вызвать конструктор из списка инициализации другого конструктора в C++/CLI так же, как это можно сделать в C#.
Пример:
ref class Foo {
Foo() {}
Foo(int i) : Foo() {}
}
Решение
Это называется «делегирующий конструктор».Он пока недоступен на языке.Но есть официальное предложение, вы найдете его в приложении F.3.1 к спецификация языка.Учитывая позицию Microsoft в отношении C++/CLI, он вряд ли увидит свет в ближайшее время.
ОБНОВЛЯТЬ:У делегирующих конструкторов была жизнь, выходящая за рамки предложения в этом приложении, они были добавлены в стандартную спецификацию языка C++11.Microsoft работает над реализацией дополнений C++11.Делегирование конструкторов наконец-то дошло до VS2013.В этой редакции они также работают на C++/CLI.
Другие советы
Вы можете сделать следующее
ref class A
{
public:
A(int p) : p(p) { this->A::A(); }
A() : p(1) {}
int p;
};
Это недопустимый код C++, но VC его отлично компилирует :)
Просто зашёл по тому же вопросу.В моем случае я использую VS2010.
Понятно, что VS2010 никогда не будет обновлен для полной реализации C++11, используйте VS2015, если вам нужно лучшее соответствие стандарту (что я и делаю, когда могу).Но для некоторых (устаревших) проектов мне все равно придется использовать VS2010.
Подход, который работает во многих случаях (для меня), — это использование частной функции со всем общим кодом инициализации.Пример:
class A
{
private:
void Inidialise() { /* common initialisation here */ }
public:
A() { Initialise(); /* specific initialisation for A() here */ }
A(bool a) { Initialise(); /* specific initialisation for A(bool) here */ }
A(int b) { Initialise(); /* specific initialisation for A(int) here */ }
/* etcetera */
}
Он не решает всех «проблем» и не предотвращает все случаи дублирования кода, но имеет большое значение.
Когда ты сказал «Я знаю, что на чистом C++ это невозможно сделать» вы ошиблись.Это можно сделать на родном C++.Для этого можно использовать оператор нового размещения.
class A
{
public:
A(int p) : p(p)
{ new(this)A(); }
A() : p(1) {}
int p;
};