Computer-Science

02. Using a Class

Preprocessor Wrappers

// prevent multiple inclusions of header file
#ifndef TIME_H
#define TIME_H

// Time class definition
class Time
{
public:
    Time(); // constructor
    void setTime(int, int, int); // set hour, minute and second
    void printuniversal(); // print time in universal-time format
    void printStandard(); // print time in standard-time format
private:
    int hour; // 0-23 (24-hour clock format)
    int minute; // 0 - 59
    int second; // 0 - 59
};

#endif // !TIME_H

Member ν•¨μˆ˜μ˜ scope

Class Scope and Accessing Class Members

클래슀 μŠ€μ½”ν”„ (class scope)와 클래슀 λ©€λ²„λ‘œμ˜ μ ‘κ·Ό

클래슀 μŠ€μ½”ν”„ (class scope)와 클래슀 λ©€λ²„λ‘œμ˜ μ ‘κ·Ό

Constructors with Default Arguments

μƒμ„±μžμ˜ λ””ν΄νŠΈ 인자 (default arguments)

#pragma once
class Time {
public:
    Time();

    void setTime(int, int, int);
    void printUniversal();
    void printStandard();
private:
    int hour;
    int minute;
    int second;
};

Destructors

클래슀 μ†Œλ©Έμž (class destructors)

μ†Œλ©Έμž (destructors)

μƒμ„±μžμ™€ μ†Œλ©Έμžμ˜ ν˜ΈμΆœμ‹œκΈ°

μƒμ„±μžμ™€ μ†Œλ©Έμžμ˜ 호좜 λ©”μ»€λ‹ˆμ¦˜

μƒμ„±μžμ™€ μ†Œλ©Έμžμ˜ 호좜 μ‹œκΈ°

객체가 global scopeμ—μ„œ μ •μ˜λ  λ•Œ (즉, μ „μ—­ λ³€μˆ˜μΌ λ•Œ)

객체가 μžλ™ 지역 λ³€μˆ˜ (local automatic variable) 일 λ•Œ (: 보톡 main ν•¨μˆ˜ μ•ˆμ— μžˆλŠ” 것)

객체가 정적 지역 λ³€μˆ˜ (static local variable) 일 λ•Œ

스크란샷 2021-10-21 α„‹α…©α„Œα…₯ᆫ 2 29 22

globalκ³Ό static은 μœ„μΉ˜κ°€ κ°™μ•„ νŠΉμ„±μ΄ β€œλΉ„μŠ·β€

μƒμ„±μžμ™€ μ†Œλ©Έμžμ˜ 호좜 μ‹œκΈ° 예제

CreatAndDestroy.h
#pragma once
#include <string>
using std::string;

class CreateAndDestory {
public:
    CreateAndDestory(int, string);
    ~CreateAndDestory();

private:
    int objectID;
    string message;
};
CreatAndDestroy.cpp
#include <iostream>
using std::cout;
using std::endl;

#include "Create.h"

void create(void); // prototype

CreateAndDestory Temp(2, "Temp");
CreateAndDestory first(1, "(global before main)"); // global object
int main()
{
    cout << "\nMAIN FUNCTION: EXECUTION BEGINS" << endl;
    CreateAndDestory second(2, "(local automatic in main)");
    static CreateAndDestory third(3, "(local static in main)");

    create(); // call function to create objects
    cout << "\nMAIN FUNCTION: EXECUTION RESUMES" << endl;
    CreateAndDestory fourth(4, "(local automatic in main)");
    cout << "\nMAIN FUNCTION: EXECUTION ENDS" << endl;
    return 0;
}

void create(void)
{
    cout << "\nCREATE FUNCTION: EXECUTION BEGINS" << endl;
    CreateAndDestory fifth(5, "(local automatic in create)");
    static CreateAndDestory sixth(6, "(local static in create)");
    CreateAndDestory seventh(7, "(local automatic in create)");
    cout << "\nCREATE FUNCTION: EXECUTION ENDS" << endl;
}
driver
#include <iostream>
using std::cout;
using std::endl;

#include "Create.h"

CreateAndDestory::CreateAndDestory(int ID, string msg)
{
    objectID = ID;
    message = msg;

    cout << "Object " << objectID << "    constructor runs    " << message << endl;
}
CreateAndDestory::~CreateAndDestory()
{
    // output newline for certain objects; helps readability
    cout << (objectID == 1 || objectID == 6 ? "\n" : "");

    cout << "Object " << objectID << "    destructor runs    "
         << message << endl;
}
OUTPUT
1   constructor runs    (global before main)

MAIN FUNCTION: EXECUTION BEGINS
2   constructor runs    (local automatic in main)
3   constructor runs    (local static in main)

CREATE FUNCTION: EXECUTION BEGINS
5   constructor runs    (local automatic in create)
6   constructor runs    (local static in create)
7   constructor runs    (local automatic in create)

CREATE FUNCTION: EXECUTION ENDS
7   destructor runs    (local automatic in create)
5   destructor runs    (local automatic in create)

MAIN FUNCTION: EXECUTION BEGINS
4   constructor runs    (local automatic in main)

MAIN FUNCTION: EXECUTION ENDS
4   destructor runs    (local automatic in create)
2   destructor runs    (local automatic in create)
6   destructor runs    (local static in create)
3   destructor runs    (local static in main)
1   destructor runs    (global before main)

Default Memberwise Assignment

λ””ν΄νŠΈ 멀버별 (memberwise) λŒ€μž…

Copy Constructor

볡사 μƒμ„±μž (copy constructor)

Shallow Copy vs. Deep Copy

const Objects and const Member Functions

μƒμˆ˜ (const)

const a = 10;
a = 20;         // error!

μƒμˆ˜ 객체 (constant objects)

const 멀버 ν•¨μˆ˜

Const μœ„μΉ˜μ— λ”°λ₯Έ 멀버 ν•¨μˆ˜μ˜ 의미

  1. ν•¨μˆ˜λͺ… λ’€μ˜ β€˜const’가 κ°€μ§€λŠ” 의미 ν•΄λ‹Ή ν•¨μˆ˜μ—μ„œ λ©€λ²„λ³€μˆ˜λ₯Ό μ½κΈ°μ „μš©(RDONLY)으둜 μ‚¬μš©ν•˜κ² λ‹€λŠ” ν‘œμ‹œμ΄λ‹€.
    즉, β€˜μ½κΈ°β€™λ§Œ 할뿐 β€˜μ“°κΈ°β€™λŠ” ν•˜μ§€μ•Šκ² λ‹€λŠ” μ˜λ―Έμ΄λ‹€.

  2. μœ„μ˜ ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ—μ„œ constκ°€ κ°€μ§€λŠ” 의미 β€˜call by referenceβ€™λ‘œ 볡사 μ˜€λ²„ν—€λ“œμ—†μ΄ μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜λ₯Ό λ§ˆμ°¬κ°€μ§€λ‘œ μ½κΈ°μ „μš©(RDONLY)으둜 μ‚¬μš©ν•˜κ² λ‹€λŠ” ν‘œμ‹œμ΄λ‹€.

  3. ν•¨μˆ˜ λ°˜ν™˜νƒ€μž… μ•žμ˜ β€˜const’가 κ°€μ§€λŠ” 의미 ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μ„ μ½κΈ°μ „μš©(RDONLY)으둜 μ‚¬μš©ν•˜κ² λ‹€λŠ” ν‘œμ‹œμ΄λ‹€.
    ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” 값은 right-hand-side에 ν•΄λ‹Ήν•œλ‹€. μ—¬κΈ°μ„œ 이 값을 &&(r-value μ°Έμ‘°)둜 받아버리면 μˆ˜μ •ν•  여지가 생긴닀. μ΄λŸ¬ν•œ κ°€λŠ₯성을 μ œκ±°ν•˜κ³  β€˜ν•΄λ‹Ή ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” 값은 λŒ€μž…μ—°μ‚°μžλ₯Ό 톡해 λ³΅μ‚¬ν•΄μ„œ μ‚¬μš©ν•˜λΌβ€™λŠ” 의미라 μƒκ°λœλ‹€.

Const μœ„μΉ˜μ— λ”°λ₯Έ 포인터 λ³€μˆ˜μ˜ 의미

  1. 포인터가 κ°€λ¦¬ν‚€λŠ” λŒ€μƒμ˜ 값을 λ³€κ²½ λͺ»ν•˜κ²Œ ν•˜λ €λ©΄ λ‹€μŒκ³Ό 같이 μ„ μ–Έν•œλ‹€.

const char* c_ptr;

char s1[] = "hello";
char s2[] = "bonjour";

const char* c_ptr = s1;
c_ptr = s2;       // μ£Όμ†Œ λ³€κ²½ κ°€λŠ₯
c_ptr[0] = 'a';   // κ°’ λ³€κ²½ λΆˆκ°€
  1. 포인터가 κ°€λ¦¬ν‚€λŠ” λŒ€μƒ(μ£Όμ†Œ)을 λ³€κ²½ λͺ»ν•˜κ²Œ ν•˜λ €λ©΄ λ‹€μŒκ³Ό 같이 μ„ μ–Έν•œλ‹€.

char* const ptr;

char s1[] = "hello";
char s2[] = "bonjour";

char* const c_ptr = s1;
c_ptr = s2;     // μ£Όμ†Œ λ³€κ²½ λΆˆκ°€
c_ptr[0] = 'a'; // κ°’ λ³€κ²½ κ°€λŠ₯
  1. λŒ€μƒκ³Ό λŒ€μƒμ˜ 값을 λͺ¨λ‘ λ³€κ²½ν•˜μ§€ λͺ»ν•˜κ²Œ ν•˜λ €λ©΄ λ‹€μŒκ³Ό 같이 μ„ μ–Έν•œλ‹€.

const char* const c_ptr;

char s1[] = "hello";
char s2[] = "bonjour";

const char* const c_ptr = s1;
c_ptr = s2;     // μ£Όμ†Œ λ³€κ²½ λΆˆκ°€
c_ptr[0] = 'a'; // κ°’ λ³€κ²½ λΆˆκ°€

Member Initializer

Composition: Objects as Members of Classes

볡합 (Composition)

볡합 κ΄€κ³„μ—μ„œ 멀버 객체 μ΄ˆκΈ°ν™”

Composition 예제

Date.h

#pragma once

class Date {
public:
    Date(int = 1, int = 1, int = 1900);
    Date(int, int);
    void print()const;
    ~Date();

private:
    int month;
    int day;
    int year;

    int checkDay(int)const;
};

Date.cpp

#include <iostream>
using std::cout;
using std::endl;

#include "Date.h"

Date::Date(int mn, int dy, int yr) {
    if (mn > 0 && mn <= 12) {
        month = mn;
    }
    else {
        month=1;
        cout << "Invalid month (" << mn << ") set to 1.\n";
    }

    year = yr;
    day = checkDay(dy);

    cout << "Date object constructor fordate ";
    print();
    cout << endl;
}
void Date::print() const {
    cout << month << '/' << day << '/' << year;
}

Date::~Date() {
    cout << "Date object destructor for date ";
    print();
    cout << endl;
}

int Date::checkDay(int testDay) const {
    static const int daysPerMonth[13] = {
        0,31,28,31,30,31,30,31,31,30,31,30,31 };
    if (testDay > 0 && testDay <= daysPerMonth[month])
        return testDay;

    if (month == 2 && testDay == 29 && (year % 400 == 0 || (year % 4 == 0 &&
        year % 100 != 0)))
        return testDay;

    cout << "Invalid day(" << testDay << ") set to 1.\n";
    return 1;
}

Employee.h

#pragma once
#include "Date.h"
class Employee {
public:
    Employee(const char* const, const char* const,
        const Date&, const Date&);
    void print() const;
    ~Employee();

private:
    char firstName[25];
    char lastName[25];
    const Date birthDate;
    const Date hireDate;
};

Employee.cpp

#include <iostream>
using std::cout;
using std::endl;

#include <cstring>
using std::strlen;
using std::strncpy;

#include "Employee.h"
#include "Date.h"

Employee::Employee(const char *const first, const char *const last,
                   const Date &dateOfBirth, const Date &dateOfHire) : birthDate(dateOfBirth),
                                                                      hireDate(dateOfHire)
{
    int length = strlen(first);
    length = (length < 25 ? length : 24);
    strncpy(firstName, first, length);
    firstName[length] = '\0';
    length = strlen(last);
    length = (length < 25 ? length : 24);
    strncpy(lastName, last, length);
    lastName[length] = '\0';

    cout << "Employee object constructor: " << firstName << ' ' << lastName << endl;
}

void Employee::print() const
{
    cout << lastName << ", " << firstName << " Hired: ";
    hireDate.print();
    cout << " Birthday: ";
    birthDate.print();
    cout << endl;
}

Employee::~Employee()
{
    cout << "Employee object destructor: " << lastName << ", " << firstName << endl;
}

driver

#include <iostream>
using std::cout;
using std::endl;

#include "Employee.h"

int main() {
    Date birth(7, 24, 1949);
    Date hire(3, 12, 1988);
    Date birth2();

    Employee manager("Bob", "Blue", birth, hire);

    cout << endl;
    manager.print();

    cout << "\n Test Date constructor with invalid values:\n";
    Date lastDayoff(14, 35, 1994);
    cout << endl;
    return 0;
}

μ‹€ν–‰ κ²°κ³Ό

image

friend Functions and friend Classes

클래슀의 friend function / friend class

Friendship κ΄€κ³„μ˜ νŠΉμ„±

Using this Pointer

This ν¬μΈν„°λž€ 무엇인가?

Dynamic Memory Management with Operators new and delete

동적 λ©”λͺ¨λ¦¬ 관리(Dynamic Memory Management)

static Class Members