Class
์ผ๋ฐ์ ์ผ๋ก c++์ ํด๋์ค๋ ๊ตฌ์กฐ์ฒด๋ณด๋ค ๋ ํจ๊ณผ์ ์ธ ๋ฌธ๋ฒ์ด๋ค. ๊ตฌ์กฐ์ฒด์ ํด๋์ค๋ ๊ฑฐ์ ํก์ฌํ๊ฒ ๋์ํ์ง๋ง, ํด๋์ค์์๋ ๋ด๋ถ์ ์ผ๋ก ํจ์ ๋ฑ์ ํฌํจํ ์ ์๋ค.
ํด๋์ค๋ ์์ ๊ฐ๋ ์ ํ๋ก๊ทธ๋๋ฐ์์ ๊ทธ๋๋ก ์ด์ฉํ ์ ์๋ค๋ ์ ์์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)์ ๊ฐ์ฆํ๋๋ก ํด์ฃผ๋ ๊ธฐ๋ณธ๋จ์์ด๋ค.
๊ตฌ์กฐ์ฒด
#include <iostream>
#include <string>
using namespace std;
struct student{
string name;
int score;
};
int main(){
struct student a;
a.name = "ํ
์คํธ";
a.score = 90;
cout << a.name << " : "<< a.score << endl;
return 0;
}
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํน์ง
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๋ค์๊ณผ ๊ฐ์ ํน์ง๋๋ฌธ์ ์์ค์ฝ๋๋ฅผ ๋ณด๋ค ๊ฐ๊ฒฐํ๊ณ ์์ฐ์ฑ ๋๊ฒ ๋ง๋ค์ด์ค๋ค.
์ถ์ํ(Abstract)
์บก์ํ(Encapsulation)
์์์ฑ(Inheritance)
์ ๋ณด ์๋(Data Hiding)
๋คํ์ฑ(Polymorphism)
์๋ฐ-๊ฐ์ฒด์งํฅํ๋ก๊ทธ๋๋ฐ์์ ๋ ์์ธํ ๊ด๋ จ ํน์ง์ ๋ณผ ์ ์๋ค.
class Student {
// ๋ฉค๋ฒ ๋ณ์๋ ์์ฑ(property)๋ผ๊ณ ๋ถ๋ฅธ๋ค.
private:
string name;
int score;
// ๊ฐ์ฒด์ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๋
public:
// ์์ฑ์
Student(string n, int s){
name = n;
score = s;
}
// ๋ฉค๋ฒ ํจ์(Method)
void show(){
cout << name << " : " << score << endl;
}
};
C++ ํด๋์ค๋ฅผ ํ์ฉํด ๋ง๋ ๋ณ์๋ฅผ instance๋ผ๊ณ ํ๋ค.
int main(){
// s1์ด ์ธ์คํด์ค
Student s1 = Student("test", 100);
}
๊ธฐ๋ณธ์ ์ผ๋ก ํ๋์ ํด๋์ค์์ ์์ฑ๋ ์ธ์คํด์ค๋ ์๋ก ๋
๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๋ฉค๋ฒ ๋ณ์๊ฐ ์ ์ฅ๋๊ณ , ๊ด๋ฆฌ๋๋ค. ๋ค๋ง ๋ฉค๋ฒ ํจ์๋ ๋ชจ๋ ์ธ์คํด์ค๊ฐ ๊ณต์ ํ๋ค๋ ์ ์์, ํจ์ ๋ด์์ ์ธ์คํด์ค๋ฅผ ๊ตฌ๋ถํ ํ์๊ฐ ์๋ค. c++ this
ํฌ์ธํฐ๋ ํฌ์ธํฐ ์๋ฃํ์ผ๋ก, ์์๋ผ๋ ์ ์์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
class Student {
// ๋ด๋ถ์ ์ธ ๊ฐ์ฒด
private:
string name;
int englishScore;
int mathScore;
int getSum() { return englishScore + mathScore;}
// ๊ฐ์ฒด์ ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๋
public:
// ์์ฑ์
Student(string name, int englishScore, int mathScore){
// ์๊ธฐ ์์ ์ ๋ฉค๋ฒ ๋ณ์์ ์ ๊ทผํ๊ธฐ ์ํด์๋ this ์ฌ์ฉ
this->name = name;
this->englishScore = englishScore;
this->mathScore = mathScore;
}
void show(){
cout << name << " : " << getSum() << endl;
}
};
์ ๊ทผ ํ์ ์
public : ํด๋์ค, ๋ฉค๋ฒ ๋ฑ์ ์ธ๋ถ๋ก ๊ณต๊ฐํ๋ค. ํด๋น ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ์ด๋ค ๊ณณ์์๋ ์ ๊ทผํ ์ ์๋ค.
private : ํด๋์ค, ๋ฉค๋ฒ ๋ฑ์ ๋ด๋ถ์์๋ง ํ์ฉํ๋ค. ์ธ๋ถ์์ ํด๋น ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ค.
ํด๋์ค๋ ๊ธฐ๋ณธ ๋ฉค๋ฒ๋ฅผ private ํํ๋ก ๊ฐ์ฃผํ๋ค.(private:
๋ฅผ ์ ์ธํ๋ฉด ๋ฉค๋ฒ๋ ์๋์ผ๋ก private ๋ฌธ๋ฒ์ ๋ฐ๋ฆ) ๋ฐ๋๋ก ๊ตฌ์กฐ์ฒด๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉค๋ฒ๋ฅผ public์ผ๋ก ๊ฐ์ฃผํ๋ค.
์์ฑ์(Constructure)
์์ฑ์๋ฅผ ์ด์ฉํด ๊ฐ์ฒด๋ฅผ ์์ฑํจ๊ณผ ๋์์ ๋ฉค๋ฒ ๋ณ์๋ฅผ ์ด๊ธฐํํ ์ ์๋ค. ์์ฑ์๋ ํน๋ณํ ๋ฉ์๋๋ก, ํด๋์ค์ ์ด๋ฆ๊ณผ ๋์ผํ ์ด๋ฆ์ ๋ฉ์๋๋ก ๊ตฌํ๋๋ค. ์์ฑ์๋ ๋ฐํ ๊ฐ์ด ์์ผ๋ฉฐ, ์ฌ๋ฌ๋ฒ ์ ์๋์ด ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ๊ฐ์ฒด๋ฅผ ์ด๊ธฐํํ ์ ์๋ค.
c++์์๋ ๋ณ๋๋ก ์์ฑ์๋ฅผ ๊ตฌํํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ ์์ฑ์(Default Constructor)๊ฐ ์ฌ์ฉ๋๋ค. ๊ธฐ๋ณธ ์์ฑ์๋ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง์ง ์์ผ๋ฉฐ, ๋ฉค๋ฒ ๋ณ์๋ 0, NULL๋ฑ์ ๊ฐ์ผ๋ก ์ด๊ธฐํ ๋๋ค.
Copy Constructor(๋ณต์ฌ ์์ฑ์)๋ ๋ค๋ฅธ ์ธ์คํด์ค์ ์ฐธ์กฐ๋ฅผ ์ธ์๋ก ๋ฐ์ ๊ทธ ์ฐธ์กฐ๋ฅผ ์ด์ฉํด ์์ ์ ์ธ์คํด์ค๋ฅผ ์ด๊ธฐํํ ์ ์๋ค. Deep Copy๋ฅผ ์ด์ฉํด ๋ง๋ค์ด์ง ์ธ์คํด์ค๋ ๊ธฐ์กด์ ์ธ์คํด์ค์ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ํ ๋น๋์ด ๋ ๋ฆฝ์ ์ด๋ค.
์์ ๋ณต์ฌ
Student(string name, int englishScore, int mathScore) : name(name), englishScore(englishScore), mathScore(mathScore) { }
๋ค์๊ณผ ๊ฐ์ด ์์ฑ์๋ฅผ ํ์ค๋ก ์ค์ฌ์ ์ธ ์ ์๋ค.
๊น์ ๋ณต์ฌ
// ๋ ๋ค๋ฅธ Student ์ธ์คํด์ค๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์ ์ด๊ธฐํํ ์ ์๋ค.
Student(const Student& other){
name = other.name;
englishScore = other.englishScore;
mathScore = other.mathScore;
}
int main(){
Student s1 = new Student("test", 100, 20);
Student s2 = Student(*s1);
}
์๋ฉธ์(Destructor)
์๋ฉธ์๋ ๊ฐ์ฒด์ ์๋ช ์ด ๋๋ฌ์ ๋ ๊ฐ์ฒด๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ค. ๊ฐ์ฒด์ ์๋ช ์ด ๋๋ฌ์ ๋ ์๋์ผ๋ก ์ปดํ์ผ๋ฌ๊ฐ ์๋ฉธ์ ํจ์๋ฅผ ํธ์ถํ๋ค.
์๋ฉธ์๋ ํด๋์ค์ ์ด๋ฆ๊ณผ ๋์ผํ๋ฉฐ ๋ฌผ๊ฒฐ ๊ธฐํธ(~
)๋ฅผ ์ด์ฉํด ์ ์ํ ์ ์๋ค.
~Student(){
cout << " ๊ฐ์ฒด๊ฐ ์๋ฉธ๋์์ต๋๋ค. " << endl;
}
int main(){
Student* student1 = new Student("dahye", 100,100);
student1->show();
Student student2 = Student(*student1);
student2.show();
delete student1; // ๋์ ํ ๋น์ ์ด์ฉํ ์ธ์คํด์ค๋ง ์ฑ๊ณต์ ์ผ๋ก ์๋ฉธํ๋ค.
// delete student2 ๋์ ํ ๋น์ ์ด์ฉํ์ง ์์ ์ธ์คํด์ค๋ ์๋ฉธ์ํฌ ์ ์๋ค.(์๋์๋ฉธ)
}
์์(Inheritance)
์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ์์ฑ์ ๊ทธ๋๋ก ๋ฌผ๋ ค ๋ฐ์ ์ฌ์ฉํ ์ ์๋ค. ์์์ ํ์ฉํด ์์ค์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ ๋๋ฆด ์ ์๋ค. ์์ ํด๋์ค๋ ํ์ ํด๋์ค(Derived Class)๋ผ๊ณ ๋ ๋ถ๋ฆฌ๋ฉฐ, ๋ถ๋ชจ ํด๋์ค์ ๋ชจ๋ ์์ฑ์ ๋ฌผ๋ ค ๋ฐ๋๋ค. :
์ ํ์ฉํด ๋ถ๋ชจํด๋์ค์ ์ฐ๊ฒฐ๋ ์ ์๋ค.
class Person {
private:
string name;
public:
Person( string name ): name(name) { }
string getName(){
return name;
}
void showName(){
cout << "์ด๋ฆ : "<< getName() << endl;
}
};
class Student : Person{
private:
int studentId;
public:
// ์์ฑ์์์ name์ Person์ name์ ์์๋ฐ์ ๊ฒ
Student(int studentId, string name) : Person(name) {
this->studentId = studentId;
}
void show(){
cout << "student id" << studentId << endl;
}
};
์์ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ๋ ๊ฐ์ฅ ๋จผ์ ๋ถ๋ชจ ํด๋์ค์ ์์ฑ์๊ฐ ํธ์ถ๋๋ค. ์์ํด๋์ค์ ์๋ช ์ด ๋คํ์ ๋๋ ์์ ํด๋์ค์ ์๋ฉธ์๊ฐ ๋จผ์ ํธ์ถ๋ ํ์ ๋ถ๋ชจ ํด๋์ค์ ์๋ฉธ์๊ฐ ํธ์ถ๋๋ค.
์ค๋ฒ๋ผ์ด๋ฉ(Overriding)
๋ถ๋ชจ ํด๋์ค์์ ์ ์๋ ํจ์๋ฅผ ๋ฌด์ํ๊ณ , ์์ ํด๋์ค์์ ๋์ผํ ์ด๋ฆ์ ํจ์๋ฅผ ์ฌ์ ์ํ๋ ๋ฌธ๋ฒ. ์ค๋ฒ๋ผ์ด๋ฉ์ ์ ์ฉํ ํจ์์ ์ํ์ ๊ธฐ์กด์ ํจ์์ ๋์ผํ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌ ๋ฐ๋๋ค.
class Person {
private:
string name;
public:
Person( string name ): name(name) { }
string getName(){
return name;
}
void showName(){
cout << "์ด๋ฆ : "<< getName() << endl;
}
};
class Student : Person{
private:
int studentId;
public:
// ์์ฑ์์์ name์ Person์ name์ ์์๋ฐ์ ๊ฒ
Student(int studentId, string name) : Person(name) {
this->studentId = studentId;
}
void show(){
cout << "student id" << studentId << endl;
}
void showName(){
cout << "student name : "<< getName() << endl;
}
};
๋ค์ค์์(Multipple Inheritance)
์ฌ๋ฌ๊ฐ์ ํด๋์ค๋ฅผ ์์๋ฐ๋ ๊ฒ์ด๋ค. ๋ค์ค์์์ ์ง์ํ์ง๋ง ๋ง์ด ์ฌ์ฉ๋์ง๋ ์๋๋ค.
class Student : Person, public Temp {
private:
int studentId;
public:
// ์์ฑ์์์ name์ Person์ name์ ์์๋ฐ์ ๊ฒ
Student(int studentId, string name) : Person(name) {
this->studentId = studentId;
}
void show(){
cout << "student id" << studentId << endl;
}
void showName(){
cout << "student name : "<< getName() << endl;
}
};
์ฌ๋ฌ ๊ฐ์ ๋ถ๋ชจ ํด๋์ค์ ๋์ผํ ๋ฉค๋ฒ๊ฐ ์กด์ฌํ ์ ์๋ค.
ํ๋์ ํด๋์ค๋ฅผ ์๋์น ์๊ฒ ์ฌ๋ฌ ๋ฒ ์์๋ฐ์ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
์ค๋ฒ๋ก๋ฉ(Overloading)
๋์ผํ ์ด๋ฆ์ ๋ฉค๋ฒ ํจ์๋ฅผ ๋ค์ํ ๋ฐฉ์์ผ๋ก ํ์ฉํ๊ธฐ ์ํด์ ์ค๋ฒ๋ก๋ฉ์ ์ฌ์ฉํ ์ ์๋ค.
ํจ์ ์ค๋ฒ๋ก๋ฉ
class Person {
private:
string name;
public:
// ์์ฑ์ ์ค๋ฒ๋ก๋ฉ
Person() { name = "ํ
์คํธ"; }
Person( string name ) : name(name) { }
void showName(){
cout << name << endl;
}
};
int main(void){
Person person1;
person1.showName(); // ํ
์คํธ
Person person2 = Person("ํ
์คํธ2");
person2.showName(); //ํ
์คํธ2
}
์ฐ์ฐ์ ์ค๋ฒ๋ก๋ฉ
๊ธฐ์กด์ ์กด์ฌํ๋ ์ฐ์ฐ์๋ง ์ ์ํ ์ ์๋ค.
๋ฉค๋ฒ ์ฐ์ฐ์(
.
), ๋ฒ์ ์ง์ ์ฐ์ฐ์(::
) ๋ฑ์ ๋ช๋ช ์ฐ์ฐ์๋ ์ค๋ฒ๋ก๋ฉ ์ฒ๋ฆฌํ ์ ์๋ค.ํผ์ฐ์ฐ์์ ๊ฐ์ ๊ท์น ๋ฑ ๊ธฐ๋ณธ์ ์ธ ์ฐ์ฐ์์ ๊ท์น์ ๋ฐ๋ผ์ผํ๋ค.
์ค๋ฒ๋ก๋ฉ์ด ๋ ์ฐ์ฐ์์ ํผ์ฐ์ฐ์ ์ค ํ๋๋ ์ฌ์ฉ์ ์ ์ ์๋ฃํ์ด์ด์ผ๋ง ํ๋ค.
#include <iostream>
#include <string>
using namespace std;
class Person {
private:
string name;
public:
Person() { name = "ํ
์คํธ"; }
Person( string name ) : name(name) { }
// ์ฐ์ฐ์ ์ค๋ฒ๋ผ์ด๋ฉ
Person operator +(const Person& other) { return Person(name + " & "+ other.name);}
void showName(){
cout << name << endl;
}
};
int main(void){
Person person1;
Person person2("ํ
์คํธ2");
Person result = person1 + person2;
result.showName(); // ํ
์คํธ & ํ
์คํธ2
}
์บก์ํ(Encapsulation)
์บก์ํ๋ ๊ด๋ จ๋ ํจ์์ ๋ฉค๋ฒ๋ค์ ๋๋๋ก ํ๋์ ํด๋์ค์์ ๊ด๋ฆฌํ๋ ๊ฒ์ด๋ค. ๋ํ, ๊ฐ์ด ์คํ๋์ด์ผ ํ๋ ๊ธฐ๋ฅ๋ค๋ ํ๋์ ํด๋์ค์ ๋ฃ์ด์ ์์ง๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ์ ์๋๋ก ํด์ผํ๋ค.
c++์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฉค๋ฒ ๋ณ์์ ์ ๊ทผํ๊ธฐ ์ํด์๋ public ๋ฉค๋ฒ ํจ์(getter)๋ฅผ ์ด์ฉํด์ผํ๋ค. ๋ค๋ง ํน์ ํ ๊ฐ์ฒด์ ๋ฉค๋ฒ ํจ์๊ฐ ์๋ ๊ฒฝ์ฐ์๋ private ๋ฉค๋ฒ์ ์ ๊ทผํด์ผ ํ ๋๊ฐ ์๋ค. ์ด๋ friend
ํค์๋๋ฅผ ์ด์ฉํ๋ฉด ํน์ ํ ๊ฐ์ฒด์ ๋ชจ๋ ๋ฉค๋ฒ์ ์ ๊ทผํ ์ ์๋ค.
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
int studentId;
string name;
public:
Student(int studentId, string name) : studentId(studentId), name(name) { }
// friend ํค์๋๋ฅผ ์ด์ฉํด ๋ฐ๋ก student.name, other.name ๊ณผ ๊ฐ์ด ๋ฐ๋ก ์ ๊ทผํ ์ ์๋ค.
friend Student operator +(const Student &student, const Student &other) {
return Student(student.studentId, student.name + " & " + other.name);
}
void showName() { cout << "์ด๋ฆ: " << name << '\n'; }
};
int main(void) {
Student student(1, "ํ
์คํธ");
Student result = student + student;
result.showName();
}
Friend Class
๋ ํด๋์ค๊ฐ ์๋ก ๋ฐ์ ํ ์ฐ๊ด์ฑ์ด ์์ผ๋ฉฐ, ์๋๋ฐฉ์ private์ ์ ๊ทผํด์ผ ํ๋ค๋ฉด ํด๋์ค ์์ฒด๋ฅผ Friend๋ก ์ ์ธํ ์ ์๋ค.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
class Time {
// friend class๋ฅผ ์ ์ธํด์ฃผ๋ฉด Date class์์ Time class ์ด์ฉ์ด ๊ฐ๋ฅํ๋ค.
friend class Date;
private:
int hour, min, sec;
public:
void setCurrentTime() {
time_t currentTime = time(NULL);
struct tm *p = localtime(¤tTime);
hour = p->tm_hour;
min = p->tm_min;
sec = p->tm_sec;
}
};
class Data{
private:
int year, month, day;
public:
Date(int year, int month, int day) : year(year), month(month), day(day){ }
// friend class์ด๋ฏ๋ก ๋ฐ๋ก ์ ๊ทผํ ์ ์๋ค.
void show(const Time &t) {
cout << "์ง์ ๋ ๋ ์ง : " << year << "๋
" << month << "์ " << day << "์ผ " << '\n';
cout << "์ง์ ๋ ๋ ์ง : " << t.hour << ":" << t.min << ":" << t.sec << '\n';
}
};
int main(void){
Time time;
time.setCurrentTime();
Date date = Date(2019, 12, 22);
date.show(time);
}
์ ์ ๋ฉค๋ฒ
ํด๋์ค์ ํฌํจ๋์ด์๋ ๋ฉค๋ฒ์ด์ง๋ง ๋ชจ๋ ๊ฐ์ฒด๊ฐ ๊ณต์ ํ๋ ๋ฉค๋ฒ์ด๋ค. ์ ์ ์ผ๋ก ์ ์ธ๋ ๋ฉค๋ฒ๋ ๋ฉ๋ชจ๋ฆฌ ์์ ์ค์ง ํ๋๋ง ํ ๋น๋์ด ๊ด๋ฆฌ๋๋ค. ์ ์ ๋ฉค๋ฒ๋ฅผ public ์ผ๋ก ์ ์ธํ๋ฉด ์ธ๋ถ์ ์ด๋ ํ ํด๋์ค์์๋ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ฉฐ, ์ ์ ๋ฉค๋ฒ๋ ์ผ๋ฐ์ ์ผ๋ก ์ฑ๊ธํค ํจํด๋ฑ์ ๋ค์ํ ๊ธฐ๋ฅ์ ์ํด ์ฌ์ฉ๋๋ค.
class Person {
private:
string name;
public:
// ์ ์ ๋ณ์
static int count;
Person(string name) : name(name) {
count ++;
}
};
int Person::count = 0;
int main(void) {
Person p1("ํ
์คํธ1");
Person p2("ํ
์คํธ2");
Person p3("ํ
์คํธ3");
cout << Person::count << endl; // 3
}
์์ ๋ฉค๋ฒ(Constant Member)
ํธ์ถ๋ ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๋ฉค๋ฒ
class Person {
private:
const int id;
string name;
public:
// ์ ์ ๋ณ์
static int count;
Person(int id, string name) : id(id), name(name) {
count ++;
}
};
int Person::count = 0;
int main(void) {
Person p1(1, "ํ
์คํธ1");
Person p2(2, "ํ
์คํธ2");
Person p3(3, "ํ
์คํธ3");
cout << Person::count << endl; // 3
}
๋คํ์ฑ(Polymorphism)
์ฌ๋ฌ ๊ฐ์ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๊ฐ ๋์ผํ ๊ธฐ๋ฅ์ ์๋ก ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ๊ธฐ๋ฅ์ ์๋ฏธ. ์๋ฅผ ๋ค์ด ๊ฒ์์์ ์นผ, ๋ํฌ, ์ด์ '๊ณต๊ฒฉ'์ด๋ผ๋ ๋์ผํ ๊ธฐ๋ฅ์ ์ํํ ์ ์๋ค.
์ถ์ํด๋์ค(Abstract Class)๋ก ๋์ผํ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ฉด ํจ๊ณผ์ ์ผ๋ก ์ค๊ณํ ์ ์๋ค.
C++ ์ปดํ์ผ๋ฌ๋ ํฌ์ธํฐ ๋ณ์๊ฐ ๊ฐ๋ฆฌํค๊ณ ์๋ ๋ณ์์ ํ์ ์ ๊ธฐ์ค์ผ๋ก ํจ์๋ฅผ ํธ์ถํ์ง ์๊ณ , ํฌ์ธํฐ์ ํ์ ์ ๊ธฐ์ค์ผ๋ก ํจ์๋ฅผ ํธ์ถํ๋ค. ์ฆ, A๋ผ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ ๋ณ์๋ A๊ฐ์ฒด์ ๋ฉค๋ฒ ํจ์๋ง์ ํธ์ถํ ์ ์๋ค.
class A{
public:
void show() {
cout << "A class" << endl;
}
};
class B : public A{
public:
void show() {
cout << "B class" << endl;
}
};
int main(void){
A* p;
A a;
B b;
p = &a;
p->show(); // A class
p = &b;
p->show(); // A class
}
p๋ผ๋ ํฌ์ธํฐ๊ฐ A๊ฐ์ฒด์ ํ์ ์ ๊ฐ๋ฆฌํค๊ธฐ ๋๋ฌธ์ A class์ show()๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ด๋ฌํ ๊ฒ์ ์ ์ ๋ฐ์ธ๋ฉ์ด๋ผ๊ณ ํ๋ค.
๋์ ๋ฐ์ธ๋ฉ(Dynamic Binding)
C++๋ ํน์ ํ ํจ์๋ฅผ ํธ์ถํ ๋ ํด๋น ํจ์์ ๋ฃจํด์ด ๊ธฐ๋ก๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ฐพ์์ผํ๋ค. ํน์ ํ ํจ์๋ฅผ ํธ์ถํ๋ ์์ค์ฝ๋์์ ์ค์ ๋ก ํจ์๊ฐ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐพ๊ธฐ ์ํด์๋ Binding ๊ณผ์ ์ด ํ์ํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ํจ์์ ํธ์ถ์ ์ปดํ์ผ ์๊ธฐ์ ๊ณ ์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ์ด์ฉํ๋ค. ์ด๋ฌํ ๋ฐฉ์์ ์ ์ ๋ฐ์ธ๋ฉ(Static Binding)์ด๋ผ๊ณ ํ๋ค. ์ผ๋ฐ์ ์ธ ๋ฉค๋ฒ ํจ์๋ ๋ชจ๋ ์ด๋ฌํ ์ ์ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๋ค.
๋ค๋ง ๊ฐ์ ํจ์๋ ํ๋ก๊ทธ๋จ์ด ์คํ๋ ๋ ๊ฐ์ฒด๋ฅผ ๊ฒฐ์ ํ๋ ์ ์์ ์ปดํ์ผ ์๊ฐ์ ๊ฐ์ฒด๋ฅผ ํน์ ํ ์ ์๋ค. ๊ฐ์ํจ์๋ ์คํ ์๊ฐ ๋ ์ฌ๋ฐ๋ฅธ ํจ์๊ฐ ์คํ๋ ์ ์๋๋ก ๋์ ๋ฐ์ธ๋ฉ์ ์ฌ์ฉํ๋ค.
class A{
public:
virtual void show() {
cout << "A class" << endl;
}
};
class B : public A{
public:
virtual void show() {
cout << "B class" << endl;
}
};
int main(void){
A* p;
A a;
B b;
p = &a;
p->show(); // A class
p = &b;
p->show(); // B class
}
๊ฐ์ํจ์
์ปดํ์ผ๋ฌ๋ ๊ฐ์ ํจ์ ํ ์ด๋ธ(Virtual Function Table)์ ์ด์ฉํด ๊ฐ์ ํจ์๋ฅผ ๋ค๋ฃจ๊ฒ ๋๋๋ฐ, ์ปดํ์ผ๋ฌ๋ ๊ฐ๊ฐ์ ๊ฐ์ฒด๋ง๋ค ๊ฐ์ ํจ์ ํ ์ด๋ธ์ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํ ๋ฉค๋ฒ๋ฅผ ์ ์ฅํ๋ค.
๊ฐ์ ํจ์๋ฅผ ํธ์ถํ๋ฉด ๊ฐ์ ํจ์ ํ ์ด๋ธ์ ์ ๊ทผํ์ฌ ์์ ์ด ํ์ํ ํจ์์ ์ฃผ์๋ฅผ ์ฐพ์ ํธ์ถํ๊ฒ ๋๋ค. ์ด๋ฌํ ๊ณผ์ ์ ๋์ ๋ฐ์ธ๋ฉ์ ํตํด ์ด๋ฃจ์ด์ง๋ฏ๋ก ์ปดํจํ ๋ฆฌ์์ค๋ฅผ ์๋ชจํ๊ฒ๋๋ค.
์ฆ, ์์ ํด๋์ค๊ฐ ์ฌ์ ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ฉค๋ฒ ํจ์๋ค์ ๊ฐ์ ํจ์๋ก ์ ์ธํ๋ ๊ฒ์ด ์ข๋ค.
๊ฐ์ ํด๋์ค์ ์๋ฉธ์
์์ ๊ด๊ณ๊ฐ ์์ผ๋ฉด์, ๋์์ ๋ฉ๋ชจ๋ฆฌ ํด์ ๋ฅผ ํด์ผํ๋ ๊ฒฝ์ฐ์๋ ๋ถ๋ชจ ํด๋์ค์ ์๋ฉธ์๋ฅผ ๊ฐ์ํจ์๋ก ์ ์ธํด์ผํ๋ค. ๋ถ๋ชจ ํฌ์ธํฐ๋ก ๊ฐ์ฒด๋ฅผ ์ญ์ ํ๋ฉด ๋ถ๋ชจ ํด๋์ค์ ์๋ฉธ์๊ฐ ํธ์ถ๋๊ธฐ ๋๋ฌธ์ด๋ค.
์์ ๊ฐ์ ํจ์(Pure Virtual Function) : ์์ ํด๋์ค์์ ๋ฐ๋์ ์ฌ์ ์๋ฅผ ํด์ฃผ์ด์ผํ๋ ํจ์์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ์์ ๊ฐ์ ํจ์๋ ๋ถ๋ชจ ํด๋์ค์์ ํจ์ ๋์์ ์ ์ํ์ง ์์ผ๋ฉฐ, ์์ ํด๋์ค์์ ๋ฐ๋์ ์ ์ํด์ผ ์ฌ์ฉํ ์ ์๋ค.
=0
ํค์๋๋ฅผ ๋ถ์ฌ์ ์ ์ธํ ์ ์๋ค.
class A{
public:
// ์์ ๊ฐ์ ํจ์
virtual void show()=0 {
cout << "A class" << endl;
}
};
class B : public A{
public:
virtual void show() {
cout << "B class" << endl;
}
};
int main(void){
A* p;
B b;
p = &b;
p->show();
}
์ถ์ํด๋์ค
์ฆ, ์ถ์ํด๋์ค๋ ํ๋ ์ด์์ ์์ ๊ฐ์ ํจ์๋ฅผ ํฌํจํ๋ ํด๋์ค๋ฅผ ์๋ฏธํ๋ค. ์์ ํด๋์ค๋ ์ถ์ ํด๋์ค๋ฅผ ์์ ๋ฐ์ ์ดํ์ ๋ฐ๋์ ์์ ๊ฐ์ ํจ์๋ฅผ ๋ชจ๋ ์ค๋ฒ๋ผ์ด๋ฉ ํด์ผ ๋น๋ก์ ํด๋น ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
ํ
ํ๋ฆฟ
Template์ ์ด์ฉํ์ฌ Generic Programming์ ์ฌ์ฉํ ์ ์๋ค.
generic programming์ ๋ฐ์ดํฐ ํ์์ ์์กดํ์ง ์๊ณ , ํ๋์ ๊ฐ์ด ์ฌ๋ฌ ๋ค๋ฅธ ๋ฐ์ดํฐ ํ์ ๋ค์ ๊ฐ์ง ์ ์๋ ๊ธฐ์ ์ ์ค์ ์ ๋์ด ์ฌ์ฌ์ฉ์ฑ์ ๋์ผ ์ ์๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์
Template์ ๋งค๊ฐ๋ณ์์ ํ์ ์ ๋ฐ๋ผ์ ํจ์ ๋ฐ ํด๋์ค๋ฅผ ์์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋๋ก ํด์ค๋ค. Template์ ์ฌ์ฉํ๋ฉด ํ์ ๋ง๋ค ๋ณ๋์ ํจ์๋ ํด๋์ค๋ฅผ ๋ง๋ค์ง ์๊ณ , ๋ค์ํ ํ์ ์์ ๋์ํ ์ ์๋ ๋จ ํ๋์ ๊ฐ์ฒด๋ฅผ ์ ์ํ ์ ์๋ค.
// template ์ ์ธ
template <typename T>
ํจ์ ํ
ํ๋ฆฟ(Function Template)
Function Template์ ๊ฐ๊ฐ์ ์๋ฃํ์ ๋ํด ์ฒ์์ผ๋ก ํธ์ถ๋ ๋, c++ ์ปดํ์ผ๋ฌ๋ ํด๋น ํ์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋๋ค. (string type์ด ๋ค์ด์ค๋ฉด string type์ ํจ์ ์ธ์คํด์ค๋ฅผ ์์ฑ)
๋ช ์์ ํน์ํ(Explicit Specialization)
ํจ์ ํ ํ๋ฆฟ์ ํน์ ํ ํ์ ์ ๋ํด ๋ช ์์ ํน์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ด๋ฌํ ๋ช ์์ ํน์ํ๋ฅผ ์ด์ฉํ๋ฉด, ํน์ ํ ํ์ ์ ๋ํด์ ํน์ํ ๊ธฐ๋ฅ์ ์ ์ํ ์ ์๋ค. ์ปดํ์ผ๋ฌ๋ ํธ์ถ๋ ํจ์์ ๋์ํ๋ ํน์ํ๋ ์ ์๋ฅผ ๋ฐ๊ฒฌํ ์ดํ์๋ ํด๋น ์ ์๋ง์ ์ฌ์ฉํ๋ค. (ํจ๊ณผ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด์ฉ)
#include <iostream>
#include <string>
using namespace std;
// template ์ ์ธ
template <typename T>
// ๋ฐ๋ก ํ์
์ ์ ์ธํ์ง ์๋๋ค.
// template์ ์ฌ์ฉํด ์๋ฃํ์ ์ ํ ๋ฐ์ง ์๊ณ ํจ์๋ฅผ ๊ตฌํํ ์ ์๋ค.
void change(T& a, T& b){
T temp;
temp = a;
a = b;
b = temp;
}
// ๋ช
์์ ํน์ํ
template <> void change<int>(int& a, int& b){
cout << "์ ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ต์ฒด" << endl;
int temp;
temp = a;
a=b;
b=temp;
}
int main(void){
int a = 6;
int b = 8;
cout << a << ':' << b << endl;
swap(a,b);
cout << a << ':' << b << endl;
}
ํด๋์ค ํ
ํ๋ฆฟ
ํด๋์ค๋ฅผ ์ผ๋ฐํํ๊ธฐ ์ํด์ Class Template์ ์ฌ์ฉํ ์ ์๋ค. Class Template์ ์ฌ์ฉํ๋ฉด ์๋ฃํ์ ๋ฐ๋ผ์ ๋ค๋ฅด๊ฒ ๋์ํ๋ ํด๋์ค ์งํฉ์ ๋ง๋ค ์ ์๋ค.
template <typename T>
class Data{
private:
T data;
public:
Data(T data) : data(data) { }
void setData(T data){ this->data = data; }
T getData() { return data; }
};
int main(void){
Data<int> data1(1);
Data<string> data2("test");
cout << data1.getData() << data2.getData() << endl;
}
default template arguments
template <typename T = int>
Smart Pointer
ํ ์์ญ์ ๋์ ํ ๋น(new
)๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํ๊ธฐ ์ํด์๋ delete
ํค์๋๋ฅผ ์ฌ์ฉํ๋๋ฐ, ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํด์ฃผ์ง ์์ผ๋ฉด ํ ๊ณต๊ฐ์ ๊ณ์ํด์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๋์(Memory Leak)๊ฐ ๋ฐ์ํ ์ ์๋ค. ์ด๋ฅผ ๋ฐฉ์งํ๊ธฐ์ํ ์๋จ์ผ๋ก ํฌ์ธํฐ์ฒ๋ผ ๋์ํ๋ class template์ธ ์ค๋งํธ ํฌ์ธํฐ(Smart Pointer)๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ค๋งํธ ํฌ์ธํฐ๋ฅผ ์ด์ฉํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ ํจ๊ณผ์ ์ผ๋ก ๋ฐฉ์งํ ์ ์์ด ์ปดํจํฐ ์์คํ
์ ์์ ์ฑ์ ๋์ผ ์ ์๋ค.
Java, C#, python ๋ฑ๋ฑ์์๋ garbage collector๊ฐ ์ฐ์ด์ง ์๋ ๊ฐ์ฒด๋ค์ ์๊ฑฐํ๋ ์ญํ ์ ํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก๋ new
ํค์๋๋ก ํน์ ํ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋๋ก ์ด๊ธฐํ ํ ํ ์ค๋งํธ ํฌ์ธํฐ์ ํด๋น ํฌ์ธํฐ๋ฅผ ๋ฃ์ด์ ์ฌ์ฉํ ์ ์๋ค. ์ค๋งํธ ํฌ์ธํฐ๋ ์๋ช
์ ๋คํ์ ๋ delete
ํค์๋๋ฅผ ์ด์ฉํด ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ค์ ์๋์ผ๋ก ํด์ ํ๋ ๊ธฐ๋ฅ์ ์ํํ๋ค.
unique_ptr : ํ๋์ ์ค๋งํธ ํฌ์ธํฐ๊ฐ ํน์ ํ ๊ฐ์ฒด๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ๋ค. ํน์ ํ ๊ฐ์ฒด์ ์์ ๊ถ์ ๊ฐ์ง๊ณ ์์๋๋ง ์๋ฉธ์๊ฐ ๊ฐ์ฒด๋ฅผ ์ญ์ ํ ์ ์๋ค.
unique_ptr<int> p1(new int(10));
unique_ptr<int> p2;
cout << "p1 "<< p1 << " p2 " << p2 << '\n';
cout << "p1 "<< *p1 << '\n'; //p1 10
p2 = move(p1); // ์์ ๊ถ ์ด์
cout << "p1 "<< p1 << " p2 " << p2 << '\n';
p2.reset(); // ๋ฉ๋ชจ๋ฆฌ ํ ๋น ํด์
cout << "p1 "<< p1 << " p2 " << p2 << '\n';
// p1 0x7f7f7fc02750 p2 0x0
// p1 0x0 p2 0x7f7f7fc02750
// p1 0x0 p2 0x0
shared_ptr : ํน์ ํ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ ์ค๋งํธ ํฌ์ธํฐ๊ฐ ์ด ๋ช๊ฐ์ธ์ง๋ฅผ ์ฐธ์กฐ, ํน์ ํ ๊ฐ์ฒด๋ฅผ ์๋ก์ด ์ค๋งํธ ํฌ์ธํฐ๊ฐ ์ฐธ์กฐํ ๋๋ง๋ค ์ฐธ์กฐ ํ์(Reference Count)๊ฐ 1์ฉ ์ฆ๊ฐ, ๊ฐ ์ค๋งํธ ํฌ์ธํฐ์ ์๋ช ์ด ๋คํ ๋๋ง๋ค 1์ฉ ๊ฐ์ํ๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์ฐธ์กฐ ํ์๊ฐ 0์ด ๋๋ฉด deleteํค์๋๋ฅผ ์ด์ฉํด ๋ฉ๋ชจ๋ฆฌ์์ ๋ฐ์ดํฐ๋ฅผ ์๋์ผ๋ก ํ ๋น ํด์ ํ๋ค.
int* arr = new int[10];
arr[8] = 100;
shared_ptr<int> p1(arr);
cout << p1.use_count() << '\n'; // 1
shared_ptr<int> p2(p1);
cout << p1.use_count() << '\n'; // 2
shared_ptr<int> p3=p2;
cout << p1.use_count() << '\n'; // 3
p1.reset();
p2.reset();
cout << p1.use_count() << '\n'; // 0
p3.reset();
weak_ptr : ํ๋ ์ด์์ shared_ptr ์ธ์คํด์ค๊ฐ ์์ ํ๋ ๊ฐ์ฒด์ ๋ํ ์ ๊ทผํ ์ ์๋ค. ํ์ง๋ง ํด๋น ๊ฐ์ฒด์ ์์ ์์ ์์๋ ํฌํจ๋์ง ์๋๋ค.
int* arr = new int(1);
shared_ptr<int> sp1(arr);
weak_ptr<int> wp = sp1; // wp๋ ์ฐธ์กฐ ํ์ ๊ณ์ฐ์์ ์ ์ธ๋จ.
cout << sp1.use_count() << '\n'; // 1
cout << wp.use_count() << '\n'; // 1
if(true){
shared_ptr<int> spw = wp.lock(); // shared_ptr point ๋ฐํ
cout << sp1.use_count() << '\n'; // 2
cout << wp.use_count() << '\n'; // 2
}
// scope๋ฅผ ๋ฒ์ด๋๋ฏ๋ก sp2 ํด์
cout << sp1.use_count() << '\n'; // 1
cout << wp.use_count() << '\n'; // 1
Last updated
Was this helpful?