1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | //////////////////// /* CMemberClass.h */ //////////////////// #pragma once #include <stdint.h> namespace NamespaceTest { class CMemberClass { private: uint32_t m_uCount; public: void SetCount(uint32_t _uCount); const uint32_t GetCount(); }; static CMemberClass memberClass; /* 9-3-2 위반 해결책 Example 참고해서 작성한 코드*/ } ////////////////////// /* CMemberClass.cpp */ ////////////////////// #include "CMemberClass.h" namespace NamespaceTest { void CMemberClass::SetCount(uint32_t _uCount) { m_uCount = _uCount; } const uint32_t CMemberClass::GetCount() { return m_uCount; } } /////////////// /* CMyClass.h */ /////////////// #pragma once #include <stdint.h> #include "CMemberClass.h" namespace NamespaceTest { /* MISRA C++ 2008, Rule 9-3-2 위반 */ /* class CMyClass { private: CMemberClass m_cMemberClass; // 멤버변수 객체 선언 public: CMemberClass* GetMemberClass(); }; */ /* 9-3-2 위반 해결책 Example 참고해서 작성한 코드*/ class CMyClass { private: CMemberClass* m_pMemberClass; // 멤버변수 객체의 포인터를 선언 public: CMyClass(); // 멤버변수 초기화를 위한 생성자 추가 CMemberClass* GetMemberClass(); }; } ///////////////// /* CMyClass.cpp*/ ///////////////// #include "CMyClass.h" namespace NamespaceTest { /* MISRA C++ 2008, Rule 9-3-2 위반 */ /* CMemberClass* CMyClass::GetMemberClass() { return &m_cMemberClass; // 멤버변수 객체의 포인터를 넘겨주면, 멤버변수 객체의 포인터로 private 인자를 수정할 수 있게 됨 } */ /* 9-3-2 위반 해결책 Example 참고해서 작성한 코드*/ CMemberClass* CMyClass::GetMemberClass() { return m_pMemberClass; } CMyClass::CMyClass() : m_pMemberClass(&memberClass) // 생성자에서 멤버변수 객체의 포인터를 설정. { // 이런식으로 쓰면 Rule 9-3-2에서, 아무튼 m_pMemberClass가 멤버변수가 아니라고 함 ㅡㅡ;; // 근데 위에거랑 사실상 똑같은거 아닌지...ㅋㅋ } // 묘하게 IBM Rhapsody에서 생성된 코드랑 비슷한거 같기도..? } ////////////// /* Test.cpp */ ////////////// #include <iostream> #include "CMyClass.h" #include "CMemberClass.h" int main() { NamespaceTest::CMyClass cMyClass; cMyClass.GetMemberClass()->SetCount(10); /* 클래스의 포인터를 받아서, 외부에서 멤버변수 객체 변경이 가능해서 문제가 됨 */ NamespaceTest::CMemberClass* pMemberClass = cMyClass.GetMemberClass(); pMemberClass->SetCount(20); std::cout << cMyClass.GetMemberClass()->GetCount() << std::endl; /* 20이 출력됨 */ return 0; } | cs |
클래스의 포인터를 넘기지 말라고 하는데...
클래스를 멤버변수로 선언해서 주소값 넘기는건 안되고, 클래스 포인터를 멤버변수로 선언한 다음 생성자에서 클래스 주소를 받는건 괜찮다고 하니... 둘다 똑같은거 아닌가...? ㅋㅋㅋ
외부에서 클래스 포인터 받아가지고 조작할 수 있는건 똑같은거 같은데... 전자는 안되고, 후자는 된다니! 내로남불이야아아아앗!!
요것은 MISRA C++ 2008 규칙 캡쳐입니다 ㅋㅋ