BUG: Remove shadow declarations of NumberOfClasses in RGBGibbsPriorFilter#6254
Merged
hjmjohnson merged 2 commits intoMay 12, 2026
Merged
Conversation
Cover defaults, Set/Get round-trip via both subclass and base pointer, and MTime semantics. Establishes the API contract for the follow-up shadow-removal commit.
RGBGibbsPriorFilter shadowed MRFImageFilter's m_NumberOfClasses and m_MaximumNumberOfIterations, requiring 4 redundant accessor overrides to direct `this->m_*` at the subclass copy. Remove the shadows and overrides; preserve the subclass-specific default of 10 (vs base 50) by calling SetMaximumNumberOfIterations(10) in the constructor. GTest in preceding commit verifies zero observable API change.
619446c to
c9e5538
Compare
Member
Author
|
@greptile review |
This comment was marked as resolved.
This comment was marked as resolved.
3915420
into
InsightSoftwareConsortium:main
19 of 20 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Remove
RGBGibbsPriorFilter's redeclarations ofm_NumberOfClassesandm_MaximumNumberOfIterationsthat shadowed the inheritedMRFImageFiltermembers, along with the 4 hand-written accessor overrides that existed only to redirect at the shadow. New GTest suite confirms zero observable API change (defaults, Set/Get via subclass and base pointer, MTime semantics).The shadow and why it was wrong
itkRGBGibbsPriorFilter.hdeclared:And four hand-written accessor overrides whose only purpose was to direct
this->m_*at the subclass shadow rather than the inherited base member:Virtual dispatch through the base pointer made the shadow work correctly for
Set/Getcallers, but the design carried real costs:RGBGibbsPriorFilter::GenerateData()is a complete override that never callsSuperclass::GenerateData()).MRFImageFiltermethod that readm_NumberOfClassesorm_MaximumNumberOfIterationsdirectly would silently see stale defaults forRGBGibbsPriorFilterinstances — a regression hazard hidden by virtual dispatch.m_NumberOfClasses{0}in both classes meant one of the shadows was purely accidental — only theMaximumNumberOfIterationsshadow served the design goal of changing the default from 50 to 10.The fix
itkRGBGibbsPriorFilter.h. The inheritedMRFImageFilter::SetNumberOfClassesand friends (declared viaitkVirtualSetMacro/itkGetConstMacro) now operate on the single inherited member.itkRGBGibbsPriorFilter.h.MaximumNumberOfIterations = 10(vs base default50) by calling the inherited setter from theRGBGibbsPriorFilterconstructor:this->SetMaximumNumberOfIterations(10);.m_NumberOfClassesdefault0matches the base, so no constructor work is needed.PrintSelflines that re-printedNumberOfClassesandMaximumNumberOfIterationsalready emitted bySuperclass::PrintSelf..hxx(m_ClassifierPtr->SetNumberOfClasses(m_NumberOfClasses);) tothis->GetNumberOfClasses()— the inherited member is private in the base, so the public accessor is the right entry point.Net diff: −43 lines in the header/hxx, +2 lines.
Test methodology — characterize-then-refactor
A new
itkRGBGibbsPriorFilterGTest.cxxwas added before the fix and committed first, so the test suite establishes the observable API contract independent of the code change. The fix commit is then verified non-regressive against that suite.The 9 GTests cover:
RGBGibbsPriorFilter.DefaultNumberOfClassesIsZero— default0RGBGibbsPriorFilter.DefaultMaximumNumberOfIterationsIsTen— default10(the subclass-specific value)MRFImageFilter.DefaultMaximumNumberOfIterationsIsFifty— base default50(documents the contract difference)RGBGibbsPriorFilter.SetGetNumberOfClassesViaSubclassRGBGibbsPriorFilter.SetGetMaximumNumberOfIterationsViaSubclassRGBGibbsPriorFilter.SetGetNumberOfClassesViaBasePointer— verifies virtual dispatch throughMRFImageFilter*RGBGibbsPriorFilter.SetGetMaximumNumberOfIterationsViaBasePointer— sameRGBGibbsPriorFilter.ModifiedTimeAdvancesOnNumberOfClassesChange—MTimeadvances when the value changesRGBGibbsPriorFilter.ModifiedTimeUnchangedOnIdenticalAssignment—MTimeunchanged on no-op assignmentAll 9 pass on the pre-fix tree (commit 1) and the post-fix tree (commit 2). The pre-existing
itkRGBGibbsPriorFilterTestimage-pipeline CTest also continues to pass —RGBGibbsPriorFilter::GenerateData()now operates on the inherited fields end-to-end.Local verification
pre-commit run --all-filesclean on both commits.ctest -R "MarkovRandomFields|RGBGibbs|MRFImageFilter": 13/13 pass (9 new GTests + 2 framework + 2 existing CTests).ctest -R Segmentation: all pass exceptitkVectorThresholdSegmentationLevelSetImageFilter, which is inModules/Segmentation/LevelSets/and has zero file-level dependency on either of the modified files (verified viagrep -rln "MRFImageFilter\\|RGBGibbsPriorFilter" Modules/Segmentation/LevelSets/→ no matches). Pre-existing baseline-PNG drift unrelated to this PR.