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(&currentTime);
        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