뀨읭
접속 : 5236   Lv. 60

Category

Profile

Counter

  • 오늘 : 3545 명
  • 전체 : 2162082 명
  • Mypi Ver. 0.3.1 β
[그냥] C++ 멤버변수 객체와 정적분석 오류... (6) 2022/05/12 PM 08:41


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



클래스의 포인터를 넘기지 말라고 하는데...


클래스를 멤버변수로 선언해서 주소값 넘기는건 안되고, 클래스 포인터를 멤버변수로 선언한 다음 생성자에서 클래스 주소를 받는건 괜찮다고 하니... 둘다 똑같은거 아닌가...? ㅋㅋㅋ


외부에서 클래스 포인터 받아가지고 조작할 수 있는건 똑같은거 같은데... 전자는 안되고, 후자는 된다니! 내로남불이야아아아앗!!













img/22/05/12/180b83735baffb0a.png


img/22/05/12/180b83733c9ffb0a.png

요것은 MISRA C++ 2008 규칙 캡쳐입니다 ㅋㅋ


신고

 

카페인 중독자    친구신청

전자는 스텍 후자는 힙때문아니에요?

뀨읭    친구신청

제 생각엔 딱 붙어있는거랑(멤버변수를 클래스로 선언), 떨어져있는걸 붙인거(멤버변수를 클래스 포인터로 선언후 포인터 대입)랑 차이라고 생각하고 있습니다 ㅋㅋ

카페인 중독자    친구신청

스텍은 스코프를 빠져나가면 사라지기때문에 만약
사라진다기보다 나중에 다른값으로 바뀔수있기때문에
MyMemberClass* a;
{
MyClass b;
a = b.Get MemberClass();
}
a->GetCount();
같은짓을 하면 에러나기때문에 막는것같은데요

카페인 중독자    친구신청

MyMemberClass를 힙에 올려두면 사라지지않고 남기때문에 에러가 안나고요

뀨읭    친구신청

스택, 힙 문제가 중점이 아닌거 같은 이유는, 동적할당을 통해서 힙 메모리 사용하지말라고 되있어서 그렇습니다! (Rule 18-4-1)

카페인 중독자    친구신청

Static으로 해놓고있었네요
X