Skip to content

Commit 1986b54

Browse files
N-Dekkerhjmjohnson
authored andcommittedMar 1, 2024
ENH: Let x::New() initialize the created object by doing new x()
Replace `new x` with `new x()`, in the definitions of `itkSimpleNewMacro` and `itkFactorylessNewMacro`. This ensures that objects created by `x::New()` are "value-initialized". In practice, this will zero-initialize data members that might otherwise be left uninitialized. Added GTests to check that `x::New()` does indeed properly initialize the created object.
1 parent 69626af commit 1986b54

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed
 

‎Modules/Core/Common/include/itkMacro.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ namespace itk
312312
Pointer smartPtr = ::itk::ObjectFactory<x>::Create(); \
313313
if (smartPtr == nullptr) \
314314
{ \
315-
smartPtr = new x; \
315+
smartPtr = new x(); \
316316
} \
317317
smartPtr->UnRegister(); \
318318
return smartPtr; \
@@ -369,7 +369,7 @@ namespace itk
369369
#define itkFactorylessNewMacro(x) \
370370
static Pointer New() \
371371
{ \
372-
x * rawPtr = new x; \
372+
x * rawPtr = new x(); \
373373
Pointer smartPtr = rawPtr; \
374374
rawPtr->UnRegister(); \
375375
return smartPtr; \

‎Modules/Core/Common/test/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,7 @@ set(ITKCommonGTests
17341734
itkImageRegionGTest.cxx
17351735
itkIndexGTest.cxx
17361736
itkIndexRangeGTest.cxx
1737+
itkLightObjectGTest.cxx
17371738
itkMakeUniqueForOverwriteGTest.cxx
17381739
itkMatrixGTest.cxx
17391740
itkMersenneTwisterRandomVariateGeneratorGTest.cxx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*=========================================================================
2+
*
3+
* Copyright NumFOCUS
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
// First include the header file to be tested:
20+
#include "itkLightObject.h"
21+
#include "itkObjectFactory.h"
22+
#include <gtest/gtest.h>
23+
24+
25+
// Tests that New() does initialize the data of a derived class, even when the derived class has a defaulted
26+
// default-constructor *and* its data has no {} initializer. Uses itkSimpleNewMacro to define New().
27+
TEST(LightObject, SimpleNewInitializesDataOfDerivedClass)
28+
{
29+
class DerivedClass : public itk::LightObject
30+
{
31+
public:
32+
ITK_DISALLOW_COPY_AND_MOVE(DerivedClass);
33+
34+
using Self = DerivedClass;
35+
using Pointer = itk::SmartPointer<Self>;
36+
37+
itkSimpleNewMacro(DerivedClass);
38+
itkGetConstMacro(Data, int);
39+
40+
protected:
41+
// Defaulted default-constructor, essential to this test.
42+
DerivedClass() = default;
43+
44+
// Defaulted destructor.
45+
~DerivedClass() override = default;
46+
47+
private:
48+
int m_Data; // Without {} initializer, for the purpose of this test.
49+
};
50+
51+
EXPECT_EQ(DerivedClass::New()->GetData(), 0);
52+
}
53+
54+
55+
// Tests that New() does initialize the data of a derived class, even when the derived class has a defaulted
56+
// default-constructor *and* its data has no {} initializer. Uses itkFactorylessNewMacro to define New().
57+
TEST(LightObject, FactorylessNewInitializesDataOfDerivedClass)
58+
{
59+
class DerivedClass : public itk::LightObject
60+
{
61+
public:
62+
ITK_DISALLOW_COPY_AND_MOVE(DerivedClass);
63+
64+
using Self = DerivedClass;
65+
using Pointer = itk::SmartPointer<Self>;
66+
67+
itkFactorylessNewMacro(DerivedClass);
68+
itkGetConstMacro(Data, int);
69+
70+
protected:
71+
// Defaulted default-constructor, essential to this test.
72+
DerivedClass() = default;
73+
74+
// Defaulted destructor.
75+
~DerivedClass() override = default;
76+
77+
private:
78+
int m_Data; // Without {} initializer, for the purpose of this test.
79+
};
80+
81+
EXPECT_EQ(DerivedClass::New()->GetData(), 0);
82+
}

0 commit comments

Comments
 (0)