๐๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ์ ์ฅํ๋ ๊ฐ์ฒด ํฌ์ธํฐ ๋ณ์
C++์์ AAAํ ํฌ์ธํฐ ๋ณ์๋ AAA ๊ฐ์ฒด ๋๋ AAA๋ฅผ ์ง์ ํน์ ๊ฐ์ ์ ์ผ๋ก ์์ํ๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์๋ค.
๐ ๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ์ ์ฅํ ์ ์๋ค.
EX) Person ⊃ Student ⊃ PartTimeStudent
Person * ptr = new Student();
Person * ptr = new PartTimeStudent();
Student * ptr = new PartTimeStudent();
IS-A ๊ด๊ณ๋ก ๋ด๋ณด์!
"ํ์์ ์ฌ๋์ ์ผ์ข ์ด๋ค"
"๊ทผ๋กํ์์ ํ์์ ์ผ์ข ์ด๋ค"
"๊ทผ๋กํ์์ ์ฌ๋์ ์ผ์ข ์ด๋ค"
๐ ํ์ ํด๋์ค ๊ฐ์ฒด๋ฅผ ์์ ํด๋์ค ๊ฐ์ฒด๋ก ๋ฐ๋ผ๋ณผ ์ ์๋ ์ฆ๊ฑฐ
"ํ์์ ์ฌ๋์ด๋ค"
"๊ทผ๋กํ์์ ํ์์ด๋ค"
"๊ทผ๋กํ์์ ์ฌ๋์ด๋ค"
EX2) ๋ชจ๋ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ Employee ํด๋์ค์ ๊ฐ์ฒด๋ก ๊ฐ์ฃผ(์ฒ๋ฆฌ)ํ ์ ์๋ค.
C++ ์ปดํ์ผ๋ฌ๋ ํฌ์ธํฐ ์ฐ์ฐ์ ๊ฐ๋ฅ์ฑ ์ฌ๋ถ๋ฅผ ํ๋จํ ๋,
ํฌ์ธํฐ์ ์๋ฃํ์ ๊ธฐ์ค์ผ๋ก ํ๋จํ์ง, ์ค์ ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด์ ์๋ฃํ์ ๊ธฐ์ค์ผ๋ก ํ๋จํ์ง ์๋๋ค.
๋ฐ๋ผ์ ํฌ์ธํฐ ํ์ ํด๋นํ๋ ํด๋์ค์ ๋ฉค๋ฒ์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
์ดํดํ๊ธฐ ์ด๋ ต๋ค๋ฉด, ์ฌ๋๊ณผ ํ์์ ๋์ ํด์ ์๊ฐํด๋ณด๋ฉด ์ฝ๊ฒ ํ๋ฆฐ๋ค! ( •ฬ ω •ฬ )โง
class A{
public:
void AFunc();
}
class B : public A{
public:
void BFunc();
}
// case1
int main(void){
A * a = new B(); // ์ปดํ์ผ ok
a -> BFunc(); // ์ปดํ์ผ error. a๊ฐ ๊ฐ๋ฆฌํค๋ ๊ฒ์ A์ ์ฃผ์์ด๊ธฐ ๋๋ฌธ์ BFunc์ ์ ๊ทผX
}
// case2
int main(void){
A * a = new B(); // ์ปดํ์ผ ok
B * b = a; // ์ปดํ์ผ error. a์ b๋ ๊ฐ๋ฆฌํค๋ ๊ฒ์ด ๋ค๋ฅด๋ค.
}
// case3
int main(void){
B * b = new B(); // ์ปดํ์ผ ok
A * a -> b; // ์ปดํ์ผ ok. B๊ฐ A๋ฅผ ์์ํ์๊ธฐ ๋๋ฌธ์, B ๊ฐ์ฒด๋ A์ ๊ฐ์ฒด์ด๊ธฐ๋ ํ๋ค.
}
ํ๋ฒ ๋ ์ ๋ฆฌ!
class First{
public:
void FirstFunc();
}
class Second : public First{
public:
void SecondFunc();
}
class Third : public Second{
public:
void ThirdFunc();
}
int main(void){
Third * tptr = new Third();
Second * sptr = tptr;
First * fptr = sptr;
tptr -> FirstFunc(); (O)
tptr -> SecondFunc(); (O)
tptr -> ThirDFunc(); (O)
sptr -> FirstFunc(); (O)
sptr -> SecondFunc(); (O)
sptr -> ThirDFunc(); (X)
fptr -> FirstFunc(); (O)
fptr -> SecondFunc(); (X)
fptr -> ThirDFunc(); (X)
}
ํจ์๋ฅผ ํธ์ถํ ๋ ์ฌ์ฉ์ด ๋ ํฌ์ธํฐ์ ํ์ ๋ฐ๋ผ์ ํธ์ถ๋๋ ํจ์๊ฐ ๊ฒฐ์ ๋๋ค.
ํฌ์ธํฐ ํ์ ์ ์๋ ํจ์๊ฐ ํธ์ถ๋๋ค.
๐ฉ ๊ฐ์ํจ์(virtual)
ํจ์๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ๋ค๋ ๊ฒ์, ํด๋น ๊ฐ์ฒด์์ ํธ์ถ๋์ด์ผ ํ๋ ํจ์๋ฅผ ๋ฐ๊พผ๋ค๋ ์๋ฏธ์ธ๋ฐ, ํฌ์ธํฐ ๋ณ์์ ์๋ฃํ์ ๋ฐ๋ผ ํธ์ถ๋๋ ํจ์์ ์ข ๋ฅ๊ฐ ๋ฌ๋ผ์ง๋ ๊ฒ์ ๋ฌธ์ ๊ฐ ์์ด ๋ณด์ธ๋ค.
๊ฐ์ํจ์ ์ ์ธ์ virtual ํค์๋ ์ ์ธ์ ํตํด ์ด๋ฃจ์ด์ง๋ค.
#include <iostream>
using namespace std;
class First {
public:
virtual void MyFunc() { cout << "FirstFunc" << endl; }
// ๊ฐ์ํจ์๊ฐ ์ ์ธ๋๊ณ ๋๋ฉด, ์ด ํจ์๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ ํ๋ ํจ์๋ ๊ฐ์ํจ์๊ฐ ๋๋ค.
};
class Second : public First {
public:
virtual void MyFunc() { cout << "SecondFunc" << endl; }
// virtual๋ฅผ ์ถ๊ฐํ์ง ์์๋ ๊ด์ฐฎ์.
};
class Third : public Second {
public:
virtual void MyFunc() { cout << "ThirdFunc" << endl; }
// virtual๋ฅผ ์ถ๊ฐํ์ง ์์๋ ๊ด์ฐฎ์.
};
int main() {
Third* tptr = new Third();
Second* sptr = tptr;
First* fptr = sptr;
fptr->MyFunc();
sptr->MyFunc();
tptr->MyFunc();
// ํจ์๊ฐ ๊ฐ์ํจ์๋ก ์ ์ธ๋๋ฉด, ํด๋น ํจ์ ํธ์ถ ์, ํฌ์ธํฐ์ ์๋ฃํ์ ๊ธฐ๋ฐ์ผ๋ก ํธ์ถ๋์์ ๊ฒฐ์ X
// ํฌ์ธํฐ ๋ณ์๊ฐ ์ค์ ๋ก ๊ฐ๋ฆฌํค๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ์ฌ, ํธ์ถ์ ๋์์ ๊ฒฐ์ O
delete tptr;
return 0;
}
๋ฐฐ์ด์ ๊ตฌ์ฑํ๋ ํฌ์ธํฐ ๋ณ์๊ฐ A ํด๋์ค์ด๋ฉด, A ํด๋์ค์ ๋ฉค๋ฒ๊ฐ ์๋ ํจ์๋ค์ ์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๊ฐ์ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ํฌ์ธํฐ ๋ณ์๊ฐ ์๋ ์ค์ ๊ฐ์ฒด์ ํ์ ๋์์ผ๋ก ์ฐ์ฐ์ ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ํด๊ฒฐ ๊ฐ๋ฅํ๋ค.
๐ ์์์ ํ๋ ์ด์
์์์ ํตํด ์ฐ๊ด๋ ์ผ๋ จ์ ํด๋์ค์ ๋ํด, ๊ณตํต์ ์ธ ๊ท์ฝ์ ์ ์ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ค์ ๋ก, EmployeeHandler ํด๋์ค๋, ์ ์ฅ๋๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ Employee ๊ฐ์ฒด๋ก ๋ฐ๋ผ๋ณด๊ณ ์๋ค.
๋ฐ๋ผ์, ์๋ก์ด ํด๋์ค๊ฐ ์ถ๊ฐ๋์ด๋, EmployeeHandler ํด๋์ค๋ ๋ณ๊ฒฝ๋ ํ์๊ฐ ์๋ค.
๋ฌผ๋ก , ๊ฐ์ฒด์ ์๋ฃํ์ ๋ฐ๋ผ ํธ์ถ๋๋ ํจ์์ ์ฐจ์ด๋ ์์ด์ผ ํ๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ์ ๊ฐ์ํจ์๋ก ํด๊ฒฐ ๊ฐ๋ฅํ๋ค.
๐ฉ ์์ ๊ฐ์ํจ์์ ์ถ์(abstract) ํด๋์ค
class Employee { // ๊ณ ์ฉ์ธ ํด๋์ค
private:
char name[100]; // ์ด๋ฆ ๋ณ์
public:
Employee(const char* name) { // ๊ณ ์ฉ์ธ ์์ฑ์
strcpy_s(this->name, name);
}
void ShowYourName() const { // ์ ๋ณด(name) ์ถ๋ ฅ ํจ์
cout << "name: " << name << endl;
}
virtual int GetPay() const { // ๊ธ์ฌ ๋ฐํ ๊ฐ์ํจ์
return 0;
}
virtual void ShowSalaryInfo() const{ } // ์ ๋ณด(name, salary) ์ถ๋ ฅ ๊ฐ์ํจ์
};
์ด ํด๋์ค๋ ๊ธฐ์ด ํด๋์ค๋ก์๋ง ์๋ฏธ๋ฅผ ๊ฐ์ง ๋ฟ, ๊ฐ์ฒด์ ์์ฑ์ ๋ชฉ์ ์ผ๋ก ์ ์๋ ํด๋์ค๊ฐ ์๋๋ค.
์ด์ ๊ฐ์ด ํด๋์ค ์ค์๋ ๊ฐ์ฒด ์์ฑ์ ๋ชฉ์ ์ผ๋ก ์ ์๋์ง ์์ ํด๋์ค๋ ์กด์ฌํ๋ค.
ex ) Employee * emp = new Employee("Lee Dong Sook");
// ์ด์ ๊ฐ์ ๋ฌธ์ฅ์ ํ๋ก๊ทธ๋๋จธ์ ์ค์์ด๋ค.
// ์ด๋ฌํ ์ค์๋ ๋ฌธ์ ๊ฐ ์๋ ๋ฌธ์ฅ์ด๊ธฐ ๋๋ฌธ์, ์ปดํ์ผ๋ฌ์ ์ํด ๋ฐ๊ฒฌ๋์ง ์๋๋ค.
๐ ๋ฐ๋ผ์, ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด, '์์ ๊ฐ์ํจ์'๋ฅผ ์ ์ธํ์ฌ, ๊ฐ์ฒด์ ์์ฑ์ ๋ฌธ๋ฒ์ ์ผ๋ก ๋ง๋ ๊ฒ์ด ์ข๋ค.
๐ ์์ ๊ฐ์ํจ์
ํจ์์ ๋ชธ์ฒด๊ฐ ์ ์๋์ง ์์ ํจ์
= 0์ ํตํด, ๋ช ์์ ์ผ๋ก ๋ชธ์ฒด๋ฅผ ์ ์ํ์ง ์์์์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ฆฐ๋ค.
class Employee { // ๊ณ ์ฉ์ธ ํด๋์ค
private:
char name[100]; // ์ด๋ฆ ๋ณ์
public:
Employee(const char* name) { // ๊ณ ์ฉ์ธ ์์ฑ์
strcpy_s(this->name, name);
}
void ShowYourName() const { // ์ ๋ณด(name) ์ถ๋ ฅ ํจ์
cout << "name: " << name << endl;
}
virtual int GetPay() const = 0; // ์์ ๊ฐ์ํจ์
virtual void ShowSalaryInfo() const = 0; // ์์ ๊ฐ์ํจ์
}
์ด์ ๊ฐ์ด ๋ฉค๋ฒ ํจ์๋ฅผ ์์ ๊ฐ์ํจ์๋ก ์ ์ธํ ํด๋์ค๋ฅผ ๊ฐ๋ฆฌ์ผ ์ถ์ ํด๋์ค(abstract class)๋ผ ํ๋ค.
๐ฉ ๋คํ์ฑ
๋ชจ์ต์ ๊ฐ์ง๋ง, ํํ๊ฐ ๋ค๋ฅด๋ค. ๐ ๋ฌธ์ฅ์ ๊ฐ์๋ฐ, ๊ฒฐ๊ณผ๋ ๋ค๋ฅด๋ค.
EX) ํฌ์ธํฐ ๋ณ์ ptr์ด ์ฐธ์กฐํ๋ ๊ฐ์ฒด์ ์๋ฃํ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์คํ๊ฒฐ๊ณผ๋ ๋ค๋ฅด๋ค.
class First{
public:
virtual void SimpleFunc() { cout<<"First"<<endl; }
};
class Second : public First{
public:
virtual void SimpleFunc() { cout<<"Second"<<endl;}
};
int main(){
First * ptr = new First();
1) ptr->SimpleFunc(); // ๋์ผํ ๋ฌธ์ฅ ์กด์ฌ
delete ptr;
ptr = new Second();
2) ptr ->SimpleFunc(); // ๋์ผํ ๋ฌธ์ฅ ์กด์ฌ
delete ptr;
return 0;
}
๐ฉ ๊ฐ์ ์๋ฉธ์
๊ฐ์ํจ์ ์ธ์๋, virtual ํค์๋๋ฅผ ๋ถ์ด์ผํ ๋์
#include <iostream>
#include <cstring>
using namespace std;
class First{ // First ํด๋์ค
private:
char * strOne;
public:
First(const char *str){ // First ์์ฑ์
strOne = new char[strlen(str)+1]; // ์์ฑ์ ๋ด๋ถ์ ๋์ ํ ๋น
}
~First(){ // First ์๋ฉธ์
cout<<"~First()"<<endl;
delete [] strOne; // ์์ฑ์ ๋์ ํ ๋น ์๋ฉธ
}
};
class Second : public First{ // Second ํด๋์ค
private:
char * strTwo;
public:
Second(const char * str1, const char * str2):First(str1){ // Second ์์ฑ์
strTwo = new char[strlen(str2)+1];
}
~Second(){ // Second ์๋ฉธ์
cout<<"~Second()"<<endl;
delete [] strTwo;
}
};
int main(){
First * ptr = new Second("simple","complex"); // ๊ฐ์ฒด ์์ฑ
delete ptr; // ptr ์๋ฉธ (First ์๋ฉธ์, Second ์๋ฉธ์ ๋์ ํธ์ถ ํ์)
return 0;
}
๊ฐ์ฒด์ ์๋ฉธ์ Firstํ ํฌ์ธํฐ๋ก ๋ช ๋ นํ๊ธฐ ๋๋ฌธ์, ๋ฉ๋ชจ๋ฆฌ ๋์ ํ์์ด ๋ฐ์ํ์๋ค.
๊ฐ์ฒด์ ์๋ฉธ๊ณผ์ ์์๋ delete ์ฐ์ฐ์์ ์ฌ์ฉ๋ ํฌ์ธํฐ ๋ณ์์ ์๋ฃํ์ ์๊ด์์ด, ๋ชจ๋ ์๋ฉธ์๊ฐ ํธ์ถ๋์ด์ผ ํ๋ค.
๐ ์๋ฉธ์์ virtual ์ ์ธ์ ์ถ๊ฐํ๋ค.
virtual ~First(){
cout<<"~First()"<<endl;
delete [] strOne;
}
์๋ฉธ์๋ ์์ ํด๋์ค์ ์๋ฉธ์๋ง virtual๋ก ์ ์ธํ๋ฉด, ์์ํ๋ ์ ๋ ํด๋์ค์ ์๋ฉธ์๋ค๋ ๋ชจ๋ '๊ฐ์ ์๋ฉธ์'๋ก ์ ์ธ๋๋ค.
class First{
...
public:
virtual ~First() { ... }
};
class Second : public First{
...
public:
virtual ~Second() { ... }
};
class Third : public Second{
...
public:
virtual ~Third(){ ... }
};
int main(){
First * ptr = new Third();
delete ptr;
...
}
๐ ์๋ฉธ์ ํธ์ถ๊ณผ์
๐ฉ ์ฐธ์กฐ์
๐ ํฌ์ธํฐ/์์
C++์์ AAAํ ํฌ์ธํฐ ๋ณ์๋, AAA๊ฐ์ฒด ๋๋ AAA๋ฅผ ์ง/๊ฐ์ ์ ์ผ๋ก ์์ํ๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํฌ ์ ์๋ค. (๊ฐ์ฒด์ ์ฃผ์๊ฐ์ ์ ์ฅํ ์ ์๋ค)
Firstํ ํฌ์ธํฐ ๋ณ์ ๐ First ํด๋์ค์ ์ ์๋ MyFunc() ํจ์ ํธ์ถ
Secondํ ํฌ์ธํฐ ๋ณ์ ๐ Second ํด๋์ค์ ์ ์๋ MyFunc() ํจ์ ํธ์ถ
Thirdํ ํฌ์ธํฐ ๋ณ์ ๐ Third ํด๋์ค์ ์ ์๋ MyFunc() ํจ์ ํธ์ถ
๐ ์์ ํน์ฑ๋ค์ ์ฐธ์กฐ์์ ๊ฒฝ์ฐ์๋ ์ ์ฉ๋๋ค.
C++์์ AAAํ ์ฐธ์กฐ์๋, AAA๊ฐ์ฒด ๋๋ AAA๋ฅผ ์ง/๊ฐ์ ์ ์ผ๋ก ์์ํ๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
Firstํ ์ฐธ์กฐ์ ๐ First ํด๋์ค์ ์ ์๋ MyFunc() ํจ์ ํธ์ถ
Secondํ ์ฐธ์กฐ์ ๐ Second ํด๋์ค์ ์ ์๋ MyFunc() ํจ์ ํธ์ถ
Thirdํ ์ฐธ์กฐ์ ๐ Third ํด๋์ค์ ์ ์๋ MyFunc() ํจ์ ํธ์ถ
int main(){
Third obj; // Thirdํ ๊ฐ์ฒด obj ์์ฑ
obj.FirstFunc();
obj.SecondFunc();
obj.ThirdFunc();
obj.SimpleFunc();
Second & sref = obj; // Secondํ ์ฐธ์กฐ์๋, Second/Thirdํ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋ค.
sref.FirstFunc();
sref.SecondFunc(); // ์ปดํ์ผ๋ฌ๋ ์ฐธ์กฐ์์ ์๋ฃํ์ ๊ฐ์ง๊ณ ํจ์์ ํธ์ถ ๊ฐ๋ฅ์ฑ์ ํ๋จํ๋ค. ๋ฐ๋ผ์, Secondํ ์ฐธ์กฐ์์ด๊ธฐ ๋๋ฌธ์, ThirdFunc()๋ ์คํํ ์ ์๋ค.
sref.SimpleFunc(); // SimpleFunc()๋ ๊ฐ์ํจ์์ด๊ธฐ ๋๋ฌธ์, ์ค์ ๊ฐ์ฒด์ธ Thirdํ์ ๋ฐ๋ผ๊ฐ์ Third ํด๋์ค์ ์ ์๋ SimpleFunc() ํจ์๋ฅผ ํธ์ถํ๋ค.
First & fref = obj; // Firstํ ์ฐธ์กฐ์๋, First/Second/Thirdํ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์ ์๋ค
fref.FirstFunc(); // ์ปดํ์ผ๋ฌ๋ ์ฐธ์กฐ์์ ์๋ฃํ์ ๊ฐ์ง๊ณ ํจ์์ ํธ์ถ ๊ฐ๋ฅ์ฑ์ ํ๋จํ๋ค. ๋ฐ๋ผ์, Firstํ ์ฐธ์กฐ์์ด๊ธฐ ๋๋ฌธ์, SecondFunc(), ThirdFunc()๋ ์คํํ ์ ์๋ค.
fref.SimpleFunc(); // SimpleFunc()๋ ๊ฐ์ํจ์์ด๊ธฐ ๋๋ฌธ์, ์ค์ ๊ฐ์ฒด์ธ Thirdํ์ ๋ฐ๋ผ๊ฐ์ Third ํด๋์ค์ ์ ์๋ Simplefunc() ํจ์๋ฅผ ํธ์ถํ๋ค.
return 0;
}
void Function(const First & ref) {..}
First ๊ฐ์ฒด ๋๋ First๋ฅผ ์ง/๊ฐ์ ์ ์ผ๋ก ์์ํ๋ ํด๋์ค์ ๊ฐ์ฒด๊ฐ ์ธ์์ ๋์์ด ๋๋ค.
์ธ์๋ก ์ ๋ฌ๋๋ ๊ฐ์ฒด์ ์ค์ ์๋ฃํ์ ์๊ด์์ด, ํจ์ ๋ด์์๋ First ํด๋์ค์ ์ ์๋ ํจ์๋ง ํธ์ถ๋ ์ ์์ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๋, ๊ฐ์ํจ์์ ๊ฒฝ์ฐ์๋ ์ค์ ๊ฐ์ฒด์ ์๋ฃํ์ ๊ฐ์ง๊ณ ํ๋จํ๊ธฐ ๋๋ฌธ์, ํธ์ถ ๊ฐ๋ฅํ๋ค.
์ฐธ๊ณ
https://vansoft1215.tistory.com/46?category=491026
'๐ฉโ๐ป ํ๋ก๊ทธ๋๋ฐ > ๐ C++' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[C++] ์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ (0) | 2024.04.30 |
---|---|
[C++] ๊ฐ์์ ์๋ฆฌ์ ๋ค์ค์์ (0) | 2024.04.29 |
[C++] ์์ (0) | 2024.04.23 |
[C++] ๋ณต์ฌ ์์ฑ์ | ๊น์ ๋ณต์ฌ์ ์์ ๋ณต์ฌ (0) | 2024.04.19 |
[C++] ํด๋์ค์ ๋ฐฐ์ด, this ํฌ์ธํฐ (0) | 2024.04.18 |