본문 바로가기
Language/C++

[C++_제 10장] 객체지향 개념

by 전전긍긍 2022. 5. 7.

본 포스팅은 C++로 시작하는 객체지향 프로그래밍 책을 바탕으로 작성하였습니다.

 

C++로 시작하는 객체지향 프로그래밍

『C++로 시작하는 객체지향 프로그래밍』은 구문보다는 문제 해결에 중점을 두는 문제 구동 방식을 사용한 프로그래밍에 대해 가르치고 있다. 여러 가지 상황에서 문제를 야기한 개념을 사용함

book.naver.com


key point

String 클래스

- 문자열 작성

string s("Welcome to C++"); //문자열 생성자

string s; //빈 문자열(empty string)

- 문자열 추가 (append)

string s1("welcome");
s1.append(" to C and C++", 0, 5);
s1.append(4, 'G');
cout << "s1 = " << s1 << endl; //Welcome to C GGGG

- 문자열 대입 (assign)

string s2("welcome");
s2.assign("Dallas, Texas", 0, 5);
cout << "s2 = " << s2 << endl; //Dalla

- at, clear, erase, empty 함수

at : 특정 인덱스에서 문자 검색

clear : 문자열 제거

erase : 문자열의 일부를 삭제

empty : 문자열이 비었는지 확인

string s1("welcome");
cout << s1.at(3) << endl; //인덱스 위치의 문자 반환

s1.erase(2, 3); //인덱스 2번부터 3개 제거
cout << "s1 = " << s1 << endl;

s1.clear(); //제거
cout << s1.empty() << endl; //비어있는지 확인

- length, size, capacity 함수

string s2("Welcome");
cout << s2.length() << endl; //길이 : 7
cout << s2.size() << endl; //크기 : 7
cout << s2.capacity() << endl; //용량 : 15

s2.erase(2, 3);
cout << s2.length() << endl;
cout << s2.size() << endl;
cout << s2.capacity() << endl;

- 문자열 비교 (compare)

문자열이 다른 문자열보다 크면 0보다 큰 int값, 같으면 0, 다른 문자열보다 작으면 0보다 작은 int값을 반환한다.

string s1("Welcome");
string s2("Welcomg");

cout << s1.compare(s2) << endl; //앞이 작으니까 -1 반환
cout << s2.compare(s1) << endl; //앞이 크면 1반환
cout << s1.compare("Welcome") << endl; //같으면 0반환

- 부분 문자열 구하기 (at, substr)

at함수 : 문자열로부터 단일 문자를 뽑아낼 수 있다.

substr함수 : 문자열로부터 부분 문자열을 구할 수 있다.

string s1("Welcome");

cout << s1.substr(0, 3) << endl; //0부터 3개
cout << s1.substr(3) << endl; //3부터 끝까지
cout << s1.substr(3, 3) << endl; //3부터 3개

- 문자열 검색 (find)

만약 일치하는 자료를 찾지 못한다면, string::npos (==not a position)을 반환한다. npos는 string클래스에 정의된 상수이다.

string s5("Welcome to HTML");
cout << s5.find('o') << endl; //4반환
cout << s5.find('o', 5) << endl; //인덱스 5부터 o를 찾아라

cout << s5.find("co") << endl; //return 3
if (s5.find("co", 5) == string::npos) //not position
	cout << "no more co" << endl;

- 문자열 삽입과 교체 (insert, replace)

cout << s5.insert(11, "C++ and ") << endl; //11번째에 삽압
string s6("AA");
cout << "s6 = " << s6.insert(1, 4, 'B') << endl;//인덱스 1위치에 4번 B를 삽입

string s7("Welcome to HTML");
cout << "s7 = " << s7.replace(11, 4, "C++") << endl; //11부터 4개를 제시한 문자열로 교체

함수에 객체 전달

객체값에 의한 전달 또는 참조에 의한 전달 모두 가능하다. 하지만, 값에 의한 전달은 시간이 걸리고 메모리 공간이 추가로 필요하므로 참조에 의한 전달이 더 효율적이다.

(* 참조에 의한 전달 : 객체의 별명이 생기는 것)

#include <iostream>
using namespace std;

class Count {
public:
	int count;

	Count(int c) {
		count = c;
	}
	Count() {
		count = 0;
	}
};

void increment(Count& c, int times) {
	c.count++;
	times++;
}

int main() {
	Count myCount;
	int times = 0;

	for (int i = 0; i < 100; i++) {
		increment(myCount, times);
	}

	cout << "myCount.count is " << myCount.count;
	cout << " times is " << times;

	return 0;
}

//myCount.count is 100 times is 0

객체의 배열

객체의 배열 생성 가능

Circle circleArray[10];

인스턴스 멤버와 정적 멤버

정적 변수는 클래스의 모든 객체들에 공유된다. 정적 함수는 클래스의 인스턴스 멤버에 접근할 수 없다.

static int numberOfObject; //정적변수
static int getNumberOfObject(); //정적함수

- 정적 변수 (static variable) : 클래스의 모든 인스턴스가 데이터를 공유. 즉, 공통 메모리 위치의 변수에 값을 저장한다.

- 정적 함수 : 클래스의 인스턴스를 생성하지 않고 호출될 수 있다.

(* 인스턴스 함수는 특정 인스턴스에 의해서만 호출될 수 있다.)

(* 인스턴스에 속하는 인스턴스 변수는 다른 변수와 서로 독립적인 메모리 저장 공간을 갖는다. 정적 변수는 같은 클래스의 모든 인스턴스에 의해 공유된다.)

//정적함수를 호출
ClassName::functionName(arguments);

//정적변수를 호출
ClassName::staticVariable;

- 인스턴스 함수와 데이터 필드는 인스턴스에 속하며, 인스턴스가 생성된 후에만 사용될 수 있다. 이들은 특정 인스턴스로부터 접근이 가능하며, 정적 함수와 정적 데이터 필드는 클래스 이름뿐만 아니라 클래스의 어떤 인스턴스로부터도 접근이 가능하다.

- 정적 변수와 정적 함수는 객체를 생성하지 않고 접근할 수 있다.

- 클래스 밖 cpp파일에서 초기화해야 한다.

- 인스턴스 또는 정적으로 선언을 결정하는 기준은 무엇인가 ? -> 특정 인스턴스에 독립적이라면 인스턴스 변수나 함수여야 하고, 종속적이라면 정적 변수나 함수여야 한다.


상수 멤버 함수

상수 멤버 함수(constant member function) : 함수가 객체 내의 어떤 데이터 필드 값을 변경하지 못하도록 컴파일러에게 알려줌.

const

- 함수가 전달된 객체를 변경하지 않는 경우 const키워드를 사용하며 매개변수를 상수로 정의한다.

- 오직 인스턴스 멤버 함수만이 상수 함수로 정의될 수 있다. -> 상수함수가 방어적 프로그래밍을 위한 것이기 때문.

- const 객체는 const 멤버 함수만 호출할 수 있으므로, 멤버 변수를 바꾸지 않는 함수는 전부 const 함수로 만들어야 한다.


프로그래밍 실습 (코드는 더보기에서 확인)

10.12 (Srick 클래스) 다음 내용을 포함하는 Stock이라는 이름의 클래스를 설계하여라.

더보기

📍Stock.h

#ifndef STOCK_H
#define STOCK_H

#include <string>
using namespace std;

class Stock {
private:
	string Symbol;
	string Name;
	double previousClosingPrice;
	double currentPrice;
public:
	Stock();
	string getSymbol() const;
	string getName() const;
	double getPreviousClosingPrice() const;
	double getCurrentPrice() const;
	void setPreviousClosingPrice(double);
	void setCurrentPricea(double);
	double getChangePercent() const;
};


#endif // !STOCK_H

📍Stock.cpp

#include "Stock.h"
#include <string>

Stock::Stock()
{
	Symbol = "MSFT";
	Name = "Microsoft Corporation";
}

string Stock::getSymbol() const
{
	return Symbol;
}

string Stock::getName() const
{
	return Name;
}

double Stock::getPreviousClosingPrice() const
{
	return previousClosingPrice;
}

double Stock::getCurrentPrice() const
{
	return currentPrice;
}

void Stock::setPreviousClosingPrice(double newPre)
{
	previousClosingPrice = newPre;
}

void Stock::setCurrentPricea(double newCurrent)
{
	currentPrice = newCurrent;
}

double Stock::getChangePercent() const
{
	return (currentPrice - previousClosingPrice) / previousClosingPrice;
}

📍main.cpp

#include "Stock.h"
#include <iostream>
using namespace std;

int main() {
	Stock stock1;
	stock1.setPreviousClosingPrice(27.5);

	stock1.setCurrentPricea(27.6);

    cout << "Previous Closing Price: " <<
        stock1.getPreviousClosingPrice() << endl;
    cout << "Current Price: " <<
        stock1.getCurrentPrice() << endl;
    cout << "Percentage Change: " <<
        stock1.getChangePercent() << endl;

    return 0;
}