Уже есть много полезных ответов, но я постараюсь добавить немного, может быть, это кому-нибудь поможет.
Прежде всего, как уже упоминалось, разыменование nullptr
или неверного указателя (адреса) не вызывает исключения в стандарте C ++. MSVC поддерживает его с помощью Структурной обработки исключений , но он не переносим. Подробнее об этом читайте в этом ответе .
Блок try функции в конструкторе не позволяет вам подавить исключение, он будет распространяться в любом случае, если вы не выбросите другое. И когда вы вводите предложение catch, все члены класса уже уничтожены. Таким образом, единственное правдоподобное, что вы можете сделать в нем, это как-то зарегистрировать ошибку или, возможно, изменить некоторые глобальные переменные. Вот почему он считается более или менее бесполезным.
Что касается вашего исходного кода
Test2(Test* pTest):m_pTest(pTest), m_nDuplicateID(pTest->getTestID())
{
}
вы можете использовать троичный оператор для проверки нулевой pTest только в списке инициализаторов и делать некоторые соответствующие действия в случае, если он нулевой - просто установите m_nDuplicateID в nullptr или какое-либо другое значение в зависимости от его типа, вызовите другую функцию и используйте ее тип возврата и т. д .:
Test2(Test* pTest):
m_pTest(pTest),
m_nDuplicateID( pTest ? pTest->getTestID() : /*some value or call*/ )
{
}
вы могли бы даже использовать несколько вложенных тернарных операторов для создания более сложных потоков выполнения.
И просто для полноты, это не относится к вашему коду, но он может утомить кого-то в той же ситуации. Если вы использовали член своего класса m_pTest для инициализации m_nDuplicateID, это будет зависеть от порядка этих членов в объявлении класса, потому что члены класса в списке инициализатора инициализируются в порядке объявления, а не в том порядке, в котором они появляются в самом списке инициализатора. , так что это может быть проблемой, и лучше избегать зависимостей порядка инициализации членов:
class A
{
A( B* pTest );
int m_nDuplicateID;
B* m_pTest;
};
A::A( B* pTest ) :
m_pTest( pTest ),
m_nDuplicateID( m_pTest->someMethod() ) // here m_pTest isn't initialized yet,
// so access violation probably
{
}