언어 자료구조 알고리즘/Escort C++

[C++] 집합(Aggregation)관계와 구성(Composition) 관계

언제나휴일 2016. 4. 15. 13:47
반응형

4. 2 집합(Aggregation) 과 구성(Composition)

 

 학생과 책의 관계처럼 "철수라는 학생은 책을 가지고 있다."라는 논리적 관계를 집합이라 합니다. 집합 관계에서는 소유 개체와 피 소유 개체의 생성 시기와 소멸 시기가 같지 않아도 됩니다. 이와 같은 관계에서 대부분 소유 개체가 피 소유 개체의 메서드를 호출하여 명령하는 직접 연관 관계가 존재하는 경우와 단순히 피 소유 개체들을 보관하는 집합체일 수 있습니다. 집합체일 경우에는 집합 관계만 표시하겠지만 직접 연관 관계가 존재하는 경우에는 집합 관계와 직접 연관 관계도 같이 표현하는 것이 좀 더 정확한 표현입니다 

 

 [그림 4.2]는 집합 관계만 있는 경우이고 [그림 4.3]은 집합 관계에 직접 연관 관계도 있는 경우입니다.


집합(Aggregation) 관계

[그림 4.2]

집합(Aggregation) 관계

[그림 4.3]

 

Stu.h  - 소유 클래스

#pragma once

#include "Book.h"

#define MAX_BOOKS           1000

class Stu

{

    string name;

    Book *books[MAX_BOOKS];

    int bcnt;

public:

    Stu(string _name);

    bool PushBook(Book *book);

    Book *GetAt(int index);

    int GetBCnt()const;

    void View()const;

};

  

Stu.cpp

#include "Stu.h"

Stu::Stu(string _name):name(_name),bcnt(0) //비 상수 멤버 필드도 초기화 기법 사용 가능함

{

}

bool Stu::PushBook(Book *book)

{

    if(bcnt < MAX_BOOKS)

    {

        books[bcnt] = book;

        bcnt++;

        return true;

    }

    return false;

}

Book *Stu::GetAt(int index)

{

    if((index>=0)&&(index<bcnt))

    {

        return books[index];

    }

    return 0;

}

int Stu::GetBCnt()const

{

    return bcnt;

}

void Stu::View()const

{

    cout<<"학생 이름:"<<name<<endl<<"갖고 있는 책 수:"<<bcnt<<endl;

    for(int i = 0; i<bcnt ; i++)

    {

        books[i]->View();

    }

}

  

Book.h 피 소유 클래스

#pragma once

#include <iostream>

#include <string>

using std::cout;

using std::endl;

using std::string;

class Book

{

    string name;

public:

    Book(string _name);

    ~Book(void);

    void View()const;

};

 

 

Book.cpp

#include "Book.h"

 

Book::Book(string _name)

{

    name = _name;

}

 

Book::~Book(void)

{

}

void Book::View()const

{

    cout<<"도서명:"<<name<<endl;

}

  

 다음의 예제 코드를 보면 소유 개체와 피 소유 개체가 생성되는 과정과 소멸하는 과정이 종속적이지 않은 형태를 지니고 있음을 확인할 수 있습니다. 이와 같은 집합 관계는 C언어로 프로그래밍할 때에도 자주 표현하는 관계입니다.

 

Test.cpp

#include "Stu.h"

 

void main()

{

    Stu *stu = new Stu("홍길동");

    Book *book = new Book("언제나 휴일");

    if(stu->PushBook(book))

    {

        cout<<"보관 성공"<<endl;

    }

    else

    {

        cout<<"보관 실패"<<endl;

    }

    stu->View();

 

    delete stu;

    delete book;

}

 

 그리고 사람과 팔의 관계처럼 "사람은 팔을 가지고 있다."라는 논리적 관계를 구성이라 합니다. 구성 관계에서는 피 소유 개체의 생성과 소멸이 소유 개체의 생성과 소멸에 종속적인 것이 집합 관계와의 차이점입니다. 광의적 의미로 얘기할 때 구성은 집합의 개념까지 포함해서 얘기합니다.


구성(Composition) 관계

 [그림 4.4]

 

위의 관계에 따라 Man 클래스를 정의할 때 내부에 멤버 필드를 Arm *arm; 혹은 Arm arm;으로 지정할 수 있을 것입니다. 만약, Arm *arm;과 같이 정의하였다면 생성자에서 arm 개체를 생성하고 소멸자에서 arm 개체를 소멸하는 코드가 구현되어 있을 때 구성 관계라 할 수 있습니다.

  

Man.h

#pragma once

 

#include <string>

using std::string;

 

#include "Arm.h"

 

class Man

{

    string name;

    Arm *arm;

public:

    Man(string _name);

    ~Man(void);

};

 

 

Man.cpp

#include "Man.h"

 

Man::Man(string _name)

{

    name = _name;

    cout<<name<<"개체 생성"<<endl;

    arm = new Arm();

}

Man::~Man(void)

{

    cout<<name<<"개체 소멸"<<endl;

    delete arm;

}

  

Arm.h

#pragma once

#include <iostream>

using std::cout;

using std::endl;

class Arm

{

public:

    Arm(void);

    ~Arm(void);

};

 

Arm.cpp

#include "Arm.h"

Arm::Arm(void)

{

    cout<<"Arm 생성자"<<endl;

}

Arm::~Arm(void)

{

    cout<<"Arm 소멸자"<<endl;

}

 

Test.cpp

#include "Man.h"

void main()

{

    Man *man = new Man("홍길동");

    delete man;

}


[그림 4.5]


4장 클래스 간의 관계

(모든 동영상 강의는 무료입니다.)

반응형