πŸ“š ν˜Όμžν•˜λŠ” C++ 곡뢀 -3-

πŸ“š ν˜Όμžν•˜λŠ” C++ 곡뢀 -3-

πŸ‘€ C++

μœ„ν‚€λ…μŠ€λ₯Ό 주둜 μ°Έμ‘°ν•˜μ—¬ κ³΅λΆ€ν–ˆλ‹€.
이전 κΈ€ πŸ“š ν˜Όμžν•˜λŠ” C++ 곡뢀 -2- λ³΄λŸ¬κ°€κΈ°

Shallow copy

#include<iostream>
#include<cstring>

using std::cout;
using std::endl;

class student{
private :
    char* name;
    int age;
public :
    student(){
        name = "";
        age = 19;
    }
    
    student(char* newName, int newAge){
        int len = strlen(newName) + 1;
        name = new char[len];
        strcpy(name, newName);
        age = newAge;
    }
    /*
    student(const student& copy){
        int len = strlen(copy.name) + 1;
        name = new char[len];
        strcpy(name, copy.name);
        age = copy.age;
    }
    */
    void changeName(char* newName){
        delete [] name;
        int len = strlen(newName) + 1;
        name = new char[len];
        strcpy(name, newName);
    }
    
    void showInfo(){
        cout << "NAME : " << name << endl;
        cout << "AGE : " << age << endl;
    }
    
    ~student(){
        delete [] name;
        cout << "DESTRUCTOR CALLED" << endl;
    }
};

int main(void){
    student a("apple", 23);
    student b(a);
    a.showInfo();
    b.showInfo();
    a.changeName("lemon");
    a.showInfo();
    b.showInfo();
    return 0;
}

NAME : apple
AGE : 23
NAME : apple
AGE : 23
NAME : lemon
AGE : 23
NAME : lemon
AGE : 23
DESTRUCTOR CALLED
** Error in `./a.out’: double free or corruption (fasttop): 0x0000000001d8ec20 **
Aborted (core dumped)

λ³΅μ‚¬μƒμ„±μžλ₯Ό μ •μ˜ν•΄μ£Όμ§€ μ•Šκ³  λ³΅μ‚¬μƒμ„±μ„ν•˜λ©΄ ν¬μΈν„°λ³€μˆ˜μ˜ 경우 μ£Όμ†Œλ§Œ λ³΅μ‚¬λ˜λ―€λ‘œ λ³΅μ‚¬μƒμ„±λœ 객체와 μ›λž˜μ˜ 객체가 같은 λ©”λͺ¨λ¦¬ 곡간을 κ°€λ¦¬ν‚€λŠ” 얕은볡사가 이뀄진닀. μœ„μ˜ μ½”λ“œμ—μ„œ λ³΅μ‚¬μƒμ„±μžλ₯Ό λ”°λ‘œ μ •μ˜ ν•΄μ£Όμ§€ μ•Šμ•˜κ³  nameλ³€μˆ˜κ°€ ν¬μΈν„°λ³€μˆ˜μ΄λ―€λ‘œ 객체 a와 b의 name이 같은 곡간을 κ°€λ¦¬ν‚€κ²Œ 됐고, aκ°€ μ†Œλ©Έλ˜λ©° b의 name도 ν•¨κ»˜ μ†Œλ©Έλ˜μ–΄ 였λ₯˜κ°€ λ°œμƒν•œ 것이닀.

Deep copy

#include<iostream>
#include<cstring>

using std::cout;
using std::endl;

class student{
private :
    char* name;
    int age;
public :
    student(){
        name = "";
        age = 19;
    }
    
    student(char* newName, int newAge){
        int len = strlen(newName) + 1;
        name = new char[len];
        strcpy(name, newName);
        age = newAge;
    }
    
    student(const student& copy){
        int len = strlen(copy.name) + 1;
        name = new char[len];
        strcpy(name, copy.name);
        age = copy.age;
    }
    
    void changeName(char* newName){
        delete [] name;
        int len = strlen(newName) + 1;
        name = new char[len];
        strcpy(name, newName);
    }
    
    void showInfo(){
        cout << "NAME : " << name << endl;
        cout << "AGE : " << age << endl;
    }
    
    ~student(){
        delete [] name;
        cout << "DESTRUCTOR CALLED" << endl;
    }
};

int main(void){
    student a("apple", 23);
    student b(a);
    a.showInfo();
    b.showInfo();
    a.changeName("lemon");
    a.showInfo();
    b.showInfo();
    return 0;
}

NAME : apple
AGE : 23
NAME : apple
AGE : 23
NAME : lemon
AGE : 23
NAME : apple
AGE : 23
DESTRUCTOR CALLED
DESTRUCTOR CALLED

μ–•μ€λ³΅μ‚¬μ˜ μ˜ˆμ œμ— λ³΅μ‚¬μƒμ„±μžλ₯Ό μΆ”κ°€λ‘œ κ΅¬ν˜„ν•˜μ—¬ 값을 λ³΅μ‚¬ν•˜λ„λ‘ ν•΄μ£Όμ—ˆλ‹€. λ³΅μ‚¬μƒμ„±μžμ—μ„œ name에 λŒ€ν•΄ μƒˆλ‘œμš΄ 곡간을 λ§Œλ“€μ–΄ 값을 넣어주도둝 ν–ˆκΈ° λ•Œλ¬Έμ— μ–•μ€λ³΅μ‚¬μ²˜λŸΌ 같은 λ©”λͺ¨λ¦¬κ³΅κ°„을 가리킀지 μ•Šκ²Œλ˜κ³ , aκ°€ μ†Œλ©Έλ˜μ–΄λ„ bμ—λŠ” λ¬Έμ œκ°€ 생기지 μ•ŠλŠ”λ‹€.

Object as function parameter

#include<iostream>

using std::cout;
using std::endl;

class data{
private :
    int value;
public :
    data(int newValue){
        value = newValue;
    }
    
    ~data(){
        cout << "DESTRUCTOR CALLED" << endl;    
    }
    
    void showData(){
        cout << "VALUE : " << this->value << endl;
    }
};

void showData_Parameter(data dt){
    cout << "SHOW DATA OF PARAMETER" << endl;
    dt.showData();
}

int main(void){
    data a(3);
    a.showData();
    showData_Parameter(a);
    return 0;
}

VALUE : 3
SHOW DATA OF PARAMETER
VALUE : 3
DESTRUCTOR CALLED
DESTRUCTOR CALLED

ν•¨μˆ˜μ˜ 인자둜 객체λ₯Ό μ „λ‹¬ν•˜κ²Œλ˜λ©΄ 객체가 λ³΅μ‚¬λ˜μ–΄ μ „λ‹¬λ˜κ³ , ν•¨μˆ˜κ°€ μ‹€ν–‰λœ λ’€ μ†Œλ©Έμžκ°€ μ‹€ν–‰λœλ‹€. μ „μ—­ν•¨μˆ˜ showDataλŠ” 인자둜 data객체λ₯Ό λ°›μ•„ data의 showDataλ₯Ό ν˜ΈμΆœν•˜κ³  μ’…λ£Œλœλ‹€. mainμ—μ„œ μ „μ—­ν•¨μˆ˜ showDataλ₯Ό ν˜ΈμΆœν–ˆμœΌλ―€λ‘œ 객체 aκ°€ λ³΅μ‚¬λ˜μ–΄ ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜κ³  μ†Œλ©Έμ΄ μΌμ–΄λ‚œλ‹€. main이 μ’…λ£Œλ  λ•Œ μ›λž˜μ˜ a도 μ†Œλ©Έλ˜λ―€λ‘œ μ†Œλ©Έμžκ°€ 총 2번 ν˜ΈμΆœλ˜λŠ” 것이닀.

Const object

#include<iostream>

using std::cout;
using std::endl;

class data{
private : 
    int value;
public :
    data(int newValue){
        value = newValue;
    }
    
    void add(int operand){
        value = value + operand;
    }
    
    void showInfo() const{
        cout << value << endl;
    }
};

int main(void){
    data a(3);
    const data b(3);
    a.showInfo();
    b.showInfo();
    a.add(3);
    //b.add(3).
    a.showInfo();
    b.showInfo();
    return 0;
}

3
3
6
3

constκ°μ²΄λŠ” constν•¨μˆ˜λ§Œ μ‚¬μš©κ°€λŠ₯ν•˜λ‹€. const둜 μƒμ„±λœ κ°μ²΄λŠ” λ©€λ²„λ³€μˆ˜μ˜ 값을 λ°”κΏ€ 수 μ—†λ‹€.

Friend class

#include<iostream>

using std::cout;
using std::endl;

class one;
class two;

class one{
friend class two;
private : 
    int value;
public :
    one(){
        value = 1;
    }
    void friendInfo(two& tw);
    void showInfo(){
        cout << this->value << endl;
    }
};

class two{
private :
    int value;
public :
    two(){
        value = 2;
    }
    void friendInfo(one& on);
    void showInfo(){
        cout << this->value << endl;
    }
friend class one;
};

void one::friendInfo(two& tw){
    cout << tw.value << endl;
}
void two::friendInfo(one& on){
    cout << on.value << endl;
}

int main(void){
    one a;
    two b;
    a.showInfo();
    b.showInfo();
    a.friendInfo(b);
    b.friendInfo(a);
    return 0;
}

1
2
2
1

friend classλ₯Ό 톡해 클래슀의 λ‚΄λΆ€ μ–΄λ””μ—μ„œλ‚˜ λ‹€λ₯Έ 클래슀λ₯Ό 친ꡬ 클래슀둜 선언해쀄 수 μžˆλ‹€. μ΄λ ‡κ²Œ 친ꡬ 클래슀λ₯Ό μ„ μ–Έν•΄μ£Όλ©΄ ν•΄λ‹Ή 클래슀의 private에 μ ‘κ·Όν•  수 μžˆκ²Œλœλ‹€..!

Friend method

#include<iostream>
#include<cstring>

using std::cout;
using std::endl;

class kitty{
private :
    char * name;
    int age;
public :
    kitty(char* newName, int newAge){
        int len = strlen(newName) + 1;
        name = new char[len];
        strcpy(name, newName);
        age = newAge;
    }
    
    friend void showInfo(kitty& cat);
};

void showInfo(kitty& cat){
    cout << cat.name << endl;
    cout << cat.age << endl;
}

int main(void){
    kitty a("Kiki", 2);
    showInfo(a);
    return 0;
}

Kiki
2

클래슀 μ™ΈλΆ€μ—μ„œ 객체의 레퍼런슀λ₯Ό 인자둜 λ°›λŠ” ν•¨μˆ˜λ‘œ μ„ μ–Έν•΄μ£Όκ³  ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ friend둜 μ„ μ–Έν•΄μ£Όμ–΄ μ‚¬μš©ν•  수 μžˆλ‹€.

Static variable

#include<iostream>

using std::cout;
using std::endl;

void staticCounter(){
    static int count;
    cout << count++ <<endl;
}

void nonStaticCounter(){
    int count;
    cout << count++ <<endl;
}

int main(void){
    for(int i = 0; i < 5; i++){
        staticCounter();
        nonStaticCounter();
    }
    return 0;
}

0 0 1 0 2 0 3 0 4 0

λ³€μˆ˜μ— static이 λΆ™μœΌλ©΄ 정적 λ³€μˆ˜λ‘œ, main이 μ’…λ£Œλ  λ•Œ ν•¨κ»˜ μ†Œλ©Έλœλ‹€. ν•¨μˆ˜κ°€ μ’…λ£Œλ˜κ±°λ‚˜ 객체가 μ†Œλ©Έλ˜μ–΄λ„ μ†Œλ©Έλ˜μ§€ μ•ŠλŠ”λ‹€.

Static object

#include<iostream>

using std::cout;
using std::endl;

class test{
public :
    test(){
        cout << this << " CREATED" <<endl;
    }
    ~test(){
        cout << this << " DESTROYED" <<endl;
    }
};

void createObject(){
    static test testObject;
}

int main(void){
    int x = 0;
    if(x == 0){
        test a;
        createObject();
    }    
    return 0;
}

0x7ffc3f417d1b CREATED
0x6021b9 CREATED
0x7ffc3f417d1b DESTROYED
0x6021b9 DESTROYED

객체에 static이 λΆ™μœΌλ©΄ 정적 객체둜, μ •μ λ³€μˆ˜μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ main이 μ’…λ£Œλ  λ•Œ μ†Œλ©Έλœλ‹€.

Static member variable

#include<iostream>

using std::cout;
using std::endl;

class test{
public :
    static int id;
    test(){
        cout<<this<<" CREATED"<<endl;
    }
    void showInfo(){
        cout<<this<<" "<<this->id<<endl;
    }
};

int test::id = 999;

int main(void){
    test a;
    test b;
    test c;
    a.showInfo();
    b.showInfo();
    c.showInfo();
    return 0;
}

0x7ffd0bfdf4ed CREATED
0x7ffd0bfdf4ee CREATED
0x7ffd0bfdf4ef CREATED
0x7ffd0bfdf4ed 999
0x7ffd0bfdf4ee 999
0x7ffd0bfdf4ef 999

λ©€λ²„λ³€μˆ˜μ—λ„ static을 λΆ™μ—¬ 정적 λ©€λ²„λ³€μˆ˜λ‘œ λ§Œλ“€ 수 μžˆλ‹€. 정적 λ©€λ²„λ³€μˆ˜λ‘œ μ„ μ–Έλ˜λ©΄ ν•΄λ‹Ή 클래슀의 λͺ¨λ“  객체듀이 λͺ¨λ‘ λ™μΌν•œ 값을 κ°–λŠ”λ‹€. 정적 λ©€λ²„λ³€μˆ˜μ˜ μ΄ˆκΈ°ν™”λŠ” 클래슀의 μ™ΈλΆ€μ—μ„œ μ΄λ€„μ Έμ•Όν•˜λ©° 객체λ₯Ό 생성할 λ•Œ μƒμ„±μžλŠ” 이λ₯Ό λ¬΄μ‹œν•΄λ„ λœλ‹€.

Static method

#include<iostream>

using std::cout;
using std::endl;

class test{
public :
    static int id;
    static void idAdder(){
        id++;   
    }
    test(){
        cout<<this<<" CREATED"<<endl;
    }
    void showInfo(){
        cout<<this<<" "<<this->id<<endl;
    }
};

int test::id = 999;

int main(void){
    test a;
    test b;
    test c;
    a.showInfo();
    b.showInfo();
    c.showInfo();
    test::idAdder();
    a.showInfo();
    b.showInfo();
    c.showInfo();
    return 0;
}

0x7ffcd656dccd CREATED
0x7ffcd656dcce CREATED
0x7ffcd656dccf CREATED
0x7ffcd656dccd 999
0x7ffcd656dcce 999
0x7ffcd656dccf 999
0x7ffcd656dccd 1000
0x7ffcd656dcce 1000
0x7ffcd656dccf 1000

λ³€μˆ˜ λ˜ν•œ static이 λΆ™μœΌλ©΄ μ •μ λ©”μ†Œλ“œκ°€ λœλ‹€. 정적 λ©”μ†Œλ“œλŠ” λ‹€λ₯Έ 정적 멀버 λ³€μˆ˜ ν˜Ήμ€ 정적 λ©”μ†Œλ“œμ—λ§Œ μ ‘κ·Όν•  수 μžˆλ‹€. μ •μ λ³€μˆ˜μ™€ λ©”μ†Œλ“œλŠ” κ°μ²΄μ™€λŠ” λ¬΄κ΄€ν•˜κ²Œ λ™μž‘ν•˜λ―€λ‘œ thisλŠ” μ‚¬μš© λͺ»ν•˜κ³ , ::을 톡해 μ ‘κ·Όν•œλ‹€.

Share: Twitter Facebook
Seunghun Yang's Picture

About Seunghun Yang

Seunghun is undergraduate student at Computer Science Engineering in CNU(Chungnam National University).

Daejeon, South Korea

Comments