인덕대 C++-출처 smile han

10주차

Plki 2024. 11. 4. 16:50
`new` 연산자는 C++에서 동적 메모리를 할당하는 데 사용됩니다. 다른 프로그래밍 언어에서도 비슷한 기능을 제공하지만, 구문과 사용법이 다릅니다. 아래에 C++, Java, Python, C#, JavaScript에서의 `new` 연산자의 사용법을 정리했습니다.
### C++
C++에서 `new` 연산자는 객체나 배열의 메모리를 동적으로 할당합니다.
```cpp
int* p = new int; // 정수형 변수 하나 동적 할당
*p = 42; // 값 할당
int* arr = new int[10]; // 정수형 배열 동적 할당
delete p; // 메모리 해제
delete[] arr; // 배열 메모리 해제
```
### Java
Java에서는 `new` 키워드를 사용하여 객체를 생성합니다. 메모리 관리는 가비지 컬렉션에 의해 자동으로 이루어집니다.
```java
int[] arr = new int[10]; // 정수형 배열 생성
MyClass obj = new MyClass(); // MyClass 객체 생성
```
### Python
Python에서는 `new` 키워드가 없지만, 객체를 생성할 때 클래스 이름을 사용하여 인스턴스를 만듭니다. 메모리 관리는 가비지 컬렉션에 의해 자동으로 이루어집니다.
```python
arr = [0] * 10 # 리스트 생성 (배열과 유사)
obj = MyClass() # MyClass 객체 생성
```
### C#
C#에서도 `new` 키워드를 사용하여 객체를 생성하며, 메모리 관리는 가비지 컬렉션에 의해 이루어집니다.
```csharp
int[] arr = new int[10]; // 정수형 배열 생성
MyClass obj = new MyClass(); // MyClass 객체 생성
```
### JavaScript
JavaScript에서는 `new` 연산자를 사용하여 생성자를 통해 객체를 생성합니다. 메모리 관리는 가비지 컬렉션에 의해 자동으로 이루어집니다.
```javascript
let obj = new MyClass(); // MyClass 객체 생성
let arr = new Array(10); // 배열 생성
```
### 요약
| **언어** | **사용법** | **메모리 관리** |
|------------|---------------------------------------------|--------------------------|
| C++ | `int* p = new int;` | 수동 메모리 관리 (delete 필요) |
| Java | `int[] arr = new int[10];` | 자동 가비지 컬렉션 |
| Python | `arr = [0] * 10` | 자동 가비지 컬렉션 |
| C# | `int[] arr = new int[10];` | 자동 가비지 컬렉션 |
| JavaScript | `let obj = new MyClass();` | 자동 가비지 컬렉션 |
각 언어의 `new` 연산자의 사용법과 메모리 관리 방식을 이해하면 동적 메모리 할당 및 객체 생성을 더 잘 활용할 수 있습니다.
 
 
 
동적 메모리 할당은 프로그램 실행 중에 필요한 메모리를 런타임에 할당하는 기술입니다. C++에서는 `new` 연산자를 사용하여 동적 메모리를 할당하고, `delete`를 사용하여 해제합니다. 이 방식은 고정된 메모리 크기 대신 필요에 따라 메모리를 할당할 수 있어 유연성을 제공합니다.
### 동적 메모리 할당의 특징
1. **유연성**: 프로그램 실행 중에 메모리 크기를 조정할 수 있습니다. 예를 들어, 사용자가 입력한 데이터 양에 따라 배열의 크기를 동적으로 결정할 수 있습니다.
2. **메모리 관리**: 필요한 만큼만 메모리를 할당하고, 사용이 끝나면 해제하여 메모리 낭비를 줄일 수 있습니다.
3. **데이터 구조**: 링크드 리스트, 트리, 그래프와 같은 동적 데이터 구조를 구현할 수 있습니다. 이러한 구조는 요소의 개수가 변동성이 크기 때문에 동적 메모리가 필수적입니다.
### 동적 메모리 할당의 필요성
1. **사전 정의된 크기 제한**: 정적 메모리 할당(예: 배열의 크기를 컴파일 타임에 결정할 경우)은 크기가 고정되어 있어 유연성이 떨어집니다. 동적 메모리를 사용하면 실행 중에 필요한 만큼만 메모리를 할당할 수 있습니다.
2. **대용량 데이터 처리**: 대량의 데이터를 처리할 때, 프로그램 시작 시 모든 메모리를 미리 할당하는 것은 비효율적입니다. 동적 메모리를 사용하면 필요한 만큼만 메모리를 할당하여 효율적으로 사용할 수 있습니다.
3. **메모리 절약**: 프로그램이 필요로 하는 메모리 양이 변동할 수 있기 때문에, 동적 메모리 할당을 통해 필요한 시점에만 메모리를 사용하고, 사용이 끝나면 해제하여 메모리 낭비를 줄일 수 있습니다.
### 예제
C++에서의 간단한 동적 메모리 할당 예제입니다.
```cpp
#include <iostream>
using namespace std;
int main() {
int n;
cout << "배열의 크기를 입력하세요: ";
cin >> n;
// 동적 배열 할당
int* arr = new int[n];
// 배열 초기화
for (int i = 0; i < n; i++) {
arr[i] = i * 10;
}
// 배열 출력
for (int i = 0; i < n; i++) {
cout << arr[i] << " ";
}
cout << endl;
// 메모리 해제
delete[] arr;
return 0;
}
```
### 결론
동적 메모리 할당은 프로그램의 유연성과 효율성을 높이며, 다양한 데이터 구조를 구현할 수 있게 해줍니다. 메모리를 필요할 때만 할당하고, 사용 후에는 해제하는 것이 중요합니다. 

 

 

 

 

 

 

배열 사용한 소스

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string> //strcpy에서 오류나면 string.h로 변경
using std::cout;
class Cat {
private: //생략가능
int age;
char name[20];
// const char* name; //A
public:
Cat(int age, const char* n) {
this->age = age;
strcpy(name, n); // name=n; //A
cout << name << "고양이 객체가 만들어졌어요.\n";
}
~Cat() { cout << name << "객체 바이\n"; };
int getAge();
const char* getName();
void setAge(int age);
void setName(const char* pName);
void meow();
};
int Cat::getAge() {
return age;
}
void Cat::setAge(int age) {
this->age = age;
}
void Cat::setName(const char* pName) {
strcpy(name, pName);
//strcpy(대상주소, 원본주소);
//strcpy_s(대상주소, 대상의길이, 원본주소);
//name=pName; //A
}
const char* Cat::getName() {
return name;
}
void Cat::meow() {
cout << name << "고양이가 울어요\n";
}
int main() {
Cat nabi(1, "나비"), yaong(1, "야옹"), * pNabi;
cout << nabi.getName() << " 출생 나이는 " << nabi.getAge() << "살이다.\n";
cout << yaong.getName() << " 출생 나이는 " << yaong.getAge() << "살이다.\n";
pNabi = &nabi;
cout << pNabi->getName() << " 출생 나이는 " << pNabi->getAge() << "살이다.\n";
nabi.setName("Nabi");
nabi.setAge(3);
cout << nabi.getName() << " 나이는 " << nabi.getAge() << "살이다.\n";
yaong.meow();
nabi.meow();
return 0;
}

 

 

 

배열 안쓰고 string형으로 변한

#define _CRT_SECURE_NO_WARNINGS // Visual Studio에서 특정 경고 메시지를 억제하는 매크로
#include <iostream> // 입출력 스트림 라이브러리 포함
using std::cout; // cout을 전역 네임스페이스에서 사용
// Cat 클래스 정의
class Cat {
private: // private 접근 지정자: 클래스 외부에서 접근할 수 없음
int age; // 고양이의 나이를 저장할 변수
std::string name; // 고양이의 이름을 저장할 문자열 변수
public: // public 접근 지정자: 클래스 외부에서 접근 가능
// 생성자: 고양이 객체를 생성할 때 호출됨
Cat(int age, std::string n) {
this->age = age; // 전달받은 나이를 클래스의 age 변수에 저장
name = n; // 전달받은 이름을 클래스의 name 변수에 저장
cout << name << " 고양이 객체가 만들어졌어요.\n"; // 고양이 객체 생성 메시지 출력
}
// 소멸자: 고양이 객체가 소멸할 때 호출됨
~Cat() {
cout << name << " 객체 바이\n"; // 고양이 객체 소멸 메시지 출력
};
// 나이를 반환하는 함수
int getAge();
// 이름을 반환하는 함수
std::string getName();
// 나이를 설정하는 함수
void setAge(int age);
// 이름을 설정하는 함수
void setName(std::string pName);
// 고양이가 울 때 호출되는 함수
void meow();
};
// getAge 함수 정의: 고양이의 나이를 반환
int Cat::getAge() {
return age; // age 값을 반환
}
// setAge 함수 정의: 고양이의 나이를 설정
void Cat::setAge(int age) {
this->age = age; // 전달받은 나이로 age 변수 설정
}
// setName 함수 정의: 고양이의 이름을 설정
void Cat::setName(std::string pName) {
name = pName; // 전달받은 이름으로 name 변수 설정
}
// getName 함수 정의: 고양이의 이름을 반환
std::string Cat::getName() {
return name; // name 값을 반환
}
// meow 함수 정의: 고양이가 울 때 메시지 출력
void Cat::meow() {
cout << name << " 고양이가 울어요\n"; // 고양이의 이름과 함께 울음 메시지 출력
}
// main 함수: 프로그램의 진입점
int main() {
// 고양이 객체 nabi와 yaong 생성
Cat nabi(1, "나비"), yaong(1, "야옹"), * pNabi; // nabi와 yaong의 나이는 1살, 이름은 각각 "나비"와 "야옹"
// nabi의 이름과 나이를 출력
cout << nabi.getName() << " 출생 나이는 " << nabi.getAge() << "살이다.\n";
// yaong의 이름과 나이를 출력
cout << yaong.getName() << " 출생 나이는 " << yaong.getAge() << "살이다.\n";
// pNabi 포인터에 nabi 객체의 주소를 저장
pNabi = &nabi;
// pNabi를 통해 nabi의 이름과 나이를 출력
cout << pNabi->getName() << " 출생 나이는 " << pNabi->getAge() << "살이다.\n";
// nabi의 이름과 나이를 변경
nabi.setName("Nabi"); // 이름 변경
nabi.setAge(3); // 나이 변경
// 변경된 nabi의 이름과 나이를 출력
cout << nabi.getName() << " 나이는 " << nabi.getAge() << "살이다.\n";
// yaong과 nabi가 울 때 메시지 출력
yaong.meow();
nabi.meow();
return 0; // 프로그램 종료
}
 
 
 
컴파일 시간과 시작 시간은 소프트웨어 개발 및 실행 과정에서 중요한 개념으로, 각각의 의미와 차이를 아래와 같이 설명할 수 있습니다.

### 컴파일 시간 (Compile Time)

- **정의**: 컴파일 시간은 소스 코드가 컴파일되어 실행 가능한 프로그램으로 변환되는 과정의 시간을 말합니다. 프로그램의 소스 코드가 컴파일러에 의해 변환되고, 이 과정에서 문법 오류나 타입 오류 등이 검출됩니다.
  
- **특징**:
  - **에러 검출**: 컴파일 시간에 문법적 오류, 타입 불일치 등의 오류를 검출할 수 있습니다.
  - **코드 최적화**: 컴파일러는 코드를 최적화하여 실행 속도를 향상시킬 수 있습니다.
  - **정적 타입 언어**: C++, Java와 같은 정적 타입 언어에서 컴파일 시간이 중요합니다. 이러한 언어에서는 변수의 타입이 컴파일 시간에 결정됩니다.

### 시작 시간 (Run Time)

- **정의**: 시작 시간은 프로그램이 실행되기 시작하는 시점을 의미합니다. 이는 프로그램이 메모리에 로드되고, 사용자가 입력을 통해 프로그램과 상호작용하는 과정에서 발생합니다.

- **특징**:
  - **실행 중 오류**: 프로그램이 실행 중에 발생하는 오류(예: 배열 범위 초과, 널 포인터 참조 등)는 시작 시간에 발생합니다. 이러한 오류는 컴파일 시간에 검출되지 않습니다.
  - **동적 메모리 할당**: 프로그램 실행 중에 메모리를 동적으로 할당하거나 해제할 수 있습니다.
  - **동적 타입 언어**: Python, JavaScript와 같은 동적 타입 언어에서는 변수의 타입이 시작 시간에 결정됩니다.

### 요약

| **구분**            | **컴파일 시간**                                            | **시작 시간**                                       |
|---------------       -|----------------------------------------------|--------------------------------------------|
| **정의**            | 소스 코드가 실행 파일로 변환되는 시간     | 프로그램이 실행되기 시작하는 시간    |
| **오류 검출**    | 문법 오류, 타입 오류 등 컴파일 시 검출     | 실행 중 오류(런타임 오류) 발생           |
| **메모리 관리**| 정적 메모리 할당                                        | 동적 메모리 할당 및 해제                     |
| **예시 언어**    | C++, Java (정적 타입 언어)                        | Python, JavaScript (동적 타입 언어)   |
 
이와 같이 컴파일 시간과 시작 시간은 소프트웨어 개발의 다른 단계에서 발생하는 프로세스와 오류를 다루며, 각 단계에서의 중요성은 프로그래밍 언어와 개발 환경에 따라 다르게 나타납니다. 추가적인 질문이 있으시면 언제든지 말씀해 주세요! 

함수를 상수로 만들때는 맨뒤에 const

 

 

 

#include <iostream>
class Dog {
int age; //private 생략함
public:
int getAge() const;
void setAge(int a) { age = a; }
void view()const { std::cout << "나는 view"; }//const지정};
int Dog::getAge() const{
view(); //
return age; // 나이변경age++->age}
int main(){
Dog happy;
happy.setAge(5);
std::cout << happy.getAge();
return 0;}//age의 값 변경X
 
 
 

 

 

 

 

 

 

포인터(*)/(C, C++)

동적으로 메모리 할당할 때는 포인터 사용

 
#include <iostream>
int main()
{
int x = 1;
int * px=&x;//선언문에서 *는 포인트변수를 선언한것 - 주소 저장
//px는 포인터 변수 주소만 저장한다.
//초기화 할때 특정한 숫자를 넣는게 아닌 안정한 주소인 x에 주소를 넣는다.

 

std::cout << x<<", "<< *px;//실행문
//매번 실행 마다 주소가 바뀜-주소를 외울수 앖음
//실행문에서 *는 주소의 값을 1을 가져온것-중요(선언문과 실행문에 *은 다름것이다.)
return 0;
}

 

 
 
C++의 포인터에 대한 설명을 예시와 함께 표로 정리해보겠습니다.
### 포인터 개요

 

포인터는 변수의 메모리 주소를 저장하는 변수입니다. 이를 통해 메모리 관리와 데이터 구조를 더 효율적으로 다룰 수 있습니다.
| **항목** | **설명** |
|-------------------|-------------------------------------------------------|
| **정의** | 다른 변수의 메모리 주소를 저장하는 변수 |
| **선언** | `타입* 포인터이름;` (예: `int* p;`) |
| **초기화** | `포인터이름 = &변수이름;` (예: `p = &x;`) |
| **역참조** | `*포인터이름`으로 포인터가 가리키는 변수에 접근 |
| **NULL 포인터** | `nullptr`로 초기화하여 사용하지 않는 포인터를 나타냄 |
| **동적 메모리 할당** | `new`를 사용하여 메모리를 동적으로 할당 |
| **메모리 해제** | `delete`를 사용하여 동적으로 할당한 메모리를 해제 |
### 예제 코드
다음은 포인터를 사용하는 간단한 C++ 프로그램 예시입니다.
```cpp
#include <iostream>
using namespace std;
int main() {
int x = 42; // 정수 변수 x 선언 및 초기화
int* p = &x; // x의 주소를 p에 저장
cout << "x의 값: " << x << endl; // x의 값 출력
cout << "p가 가리키는 값: " << *p << endl; // p가 가리키는 값 출력
*p = 100; // p가 가리키는 주소의 값을 변경
cout << "x의 새 값: " << x << endl; // 변경된 x의 값 출력
// 동적 메모리 할당
int* dynamicArray = new int[5]; // 정수형 배열 동적 할당
for (int i = 0; i < 5; i++) {
dynamicArray[i] = i * 10; // 배열 초기화}
cout << "동적 배열의 값들: ";
for (int i = 0; i < 5; i++) {
cout << dynamicArray[i] << " "; // 동적 배열의 값 출력}
cout << endl;
delete[] dynamicArray; // 메모리 해제
return 0;}
```
### 예제 설명
1. **변수 선언 및 초기화**:
- `int x = 42;`: 정수형 변수 `x`를 선언하고 42로 초기화합니다.
- `int* p = &x;`: `p`는 `x`의 주소를 저장하는 포인터입니다.
2. **포인터 역참조**:
- `*p`를 사용하여 `p`가 가리키는 주소의 값을 출력하거나 변경할 수 있습니다.
3. **동적 메모리 할당**:
- `new` 키워드를 사용하여 정수형 배열을 동적으로 할당하고, 값을 초기화합니다.
- `delete[]`로 동적으로 할당된 메모리를 해제합니다.
 
 
 
C++에서 포인터는 다양한 용도로 사용됩니다. 아래에 주요 사용처를 정리해 보았습니다.
| **사용처** | **설명** |
|-------------------------|----------------------------------------------------------|
| **동적 메모리 할당** | `new`와 `delete`를 사용하여 런타임에 메모리를 할당하고 해제할 수 있습니다. |
| **배열과 문자열** | 배열의 첫 번째 요소의 주소를 가리킴으로써 배열을 쉽게 다룰 수 있습니다. |
| **함수 매개변수로 전달** | 포인터를 사용하여 함수에 인자를 전달하면, 함수 내에서 인자의 값을 직접 수정할 수 있습니다. |
| **데이터 구조** | 링크드 리스트, 트리 등과 같은 동적 데이터 구조를 구현할 때 포인터를 사용합니다. |
| **다중 포인터** | 포인터의 포인터를 사용하여 이중 배열이나 다차원 배열을 효과적으로 다룰 수 있습니다. |
| **리소스 관리** | 파일 핸들, 네트워크 소켓 등과 같은 시스템 자원을 관리하는 데 사용됩니다. |
| **성능 최적화** | 대용량 데이터 구조를 복사하는 대신 포인터를 전달하여 성능을 향상시킬 수 있습니다. |
| **객체 지향 프로그래밍** | 객체의 동적 생성 및 소멸을 관리하기 위해 포인터와 참조를 사용합니다. |
| **콜백 함수** | 포인터를 사용하여 함수의 주소를 전달하고, 특정 이벤트에 대해 호출할 수 있습니다. |
### 예시
1. **동적 메모리 할당**:
```cpp
int* arr = new int[10]; // 정수형 배열 동적 할당
delete[] arr; // 메모리 해제
```
2. **함수 매개변수로 전달**:
```cpp
void increment(int* p) {
(*p)++;
}
int x = 5;
increment(&x); // x의 값이 6으로 변경됨
```
3. **링크드 리스트**:
```cpp
struct Node {
int data;
Node* next;
};
```
이러한 사용처를 통해 C++에서 포인터의 중요성과 유용성을 이해할 수 있습니다.

 

 

 

저장하고 있는 자료형으로 갔을 떄 그곳에 무엇이 있는지 알려주는 것이 포인터 변수의 자료형

int x=1; 초기화

int *px=&x; 어떤 주소만 

실행문에서 *px는 값 출력

 

 

 

 

 

동적 메모리 할당

시험에 향상냄

 

 

 

 

new연산자는 시작 주소가 튀어 나온다.

동적애서 포인터 이용이 단점.

 

 

 

 

 

#include <iostream>
int main()
{
int x = 10; //정적 할당
//steak 저장을 처리 후 바로 삭제
int *px = new int; //동적 heap에 저장
//풀어주지 않으면 게속 남아있음 - 메모리낭비 - (꺼다 키면 풀어짐)
delete px;//동적 할당 풀어줌
return 0;
}//시험 낸적 있음

 

스택은 지역 변수만, 전역변수는 다른곳

 

 

#include <iostream>
int main()
{
int x = 10;
int *px = new int[5];
delete []px;//배열로 할당 할떄 포인터 변수 앞에 []을 써야함
return 0;
}//시험 낸적 있음

, C++에서 배열의 이름은 배열의 시작 주소를 나타냅니다. 배열의 이름은 해당 배열의 첫 번째 요소의 주소를 가리키며, 이를 통해 배열의 메모리 공간에 접근할 수 있습니다. 아래에서 더 자세히 설명하겠습니다.

### 배열 이름과 시작 주소

1. **배열 이름**:
   - 배열의 이름은 해당 배열을 참조하는 식별자입니다. 예를 들어, `int arr[5];`라는 배열이 있을 때, `arr`은 이 배열의 이름입니다.

2. **주소**:
   - 배열의 이름은 배열의 첫 번째 요소의 주소와 동일합니다. 즉, `arr`은 `&arr[0]`와 같은 값을 가집니다. 이는 `arr`을 사용하여 배열의 첫 번째 요소에 접근할 수 있음을 의미합니다.

3. **포인터와의 관계**:
   - C++에서는 배열 이름을 포인터처럼 사용할 수 있습니다. 예를 들어, `arr[i]`는 `*(arr + i)`와 동일합니다. 이는 배열의 인덱스를 통해 요소에 접근하는 방식입니다. 즉, `arr[i]`는 배열의 시작 주소에 `i`를 더한 위치에 있는 요소를 가리킵니다.

### 예제
```cpp
#include <iostream>
using namespace std;

int main() {
    int arr[5] = {10, 20, 30, 40, 50};
    
    cout << "배열 이름(arr)의 주소: " << arr << endl; // 배열의 시작 주소
    cout << "첫 번째 요소의 주소: " << &arr[0] << endl; // 첫 번째 요소의 주소
    cout << "두 번째 요소의 주소: " << &arr[1] << endl; // 두 번째 요소의 주소

    // 포인터처럼 사용
    cout << "첫 번째 요소: " << arr[0] << endl; // 10
    cout << "두 번째 요소: " << *(arr + 1) << endl; // 20 (포인터 연산)
    return 0;
}
```
### 출력 결과
```
배열 이름(arr)의 주소: 0x7ffee8d1c7b0 (예시로 나타난 주소)
첫 번째 요소의 주소: 0x7ffee8d1c7b0
두 번째 요소의 주소: 0x7ffee8d1c7b4
첫 번째 요소: 10
두 번째 요소: 20
```
### 요약
- 배열의 이름은 배열의 첫 번째 요소의 주소를 나타내며, 이를 통해 배열의 메모리 공간에 접근할 수 있습니다.
- 배열 이름은 포인터처럼 사용될 수 있으며, 배열 요소에 접근할 때 유용합니다.
이와 같은 특성 덕분에 C++에서 배열을 효율적으로 다룰 수 있습니다. 

 

주어진 C++ 코드에서 `Dog` 클래스를 사용하여 동적 메모리를 할당하고, 이를 통해 객체의 속성을 설정하고 출력하는 프로그램입니다. 코드에 대한 설명과 함께 필요한 수정을 제안하겠습니다.

### 코드 설명

```cpp
#include <iostream> // 입출력 스트림 라이브러리 포함

class Dog {
private:
    int age; // 개의 나이를 저장하는 private 멤버 변수
public:
    int getAge(); // 나이를 반환하는 public 함수
    void setAge(int a); // 나이를 설정하는 public 함수
};

// 나이 반환 함수 정의
int Dog::getAge() {
    return age; // age를 반환
}

// 나이 설정 함수 정의
void Dog::setAge(int a) {
    age = a; // age에 매개변수 a를 할당
}

int main() {
    Dog *dp; // Dog 클래스의 포인터 선언
    dp = new Dog; // Dog 객체를 동적으로 할당

    // 메모리 할당 실패 시 처리
    if (!dp) {
        std::cout << "메모리 할당 불가!";
        return 1; // 프로그램 종료
    }

    dp->setAge(5); // 동적 할당된 Dog 객체의 나이를 5로 설정
    std::cout << "메모리에 할당된 값은 " << dp->getAge() << "입니다."; // 나이 출력

    delete dp; // 동적으로 할당된 메모리 해제
    return 0; // 프로그램 종료
}
```

### 코드 수정 및 개선 사항

1. **메모리 할당 확인**: C++에서 `new` 연산자가 메모리 할당에 실패하면 예외를 발생시키므로 `if (!dp)` 체크는 필요하지 않습니다. 대신 예외 처리를 통해 안전하게 처리할 수 있습니다.

2. **주석 추가**: 각 코드 블록에 대한 설명을 추가하여 코드의 가독성을 높일 수 있습니다.

### 수정된 코드

아래는 수정된 코드입니다.

```cpp
#include <iostream> // 입출력 스트림 라이브러리 포함

class Dog {
private:
    int age; // 개의 나이를 저장하는 private 멤버 변수
public:
    int getAge(); // 나이를 반환하는 public 함수
    void setAge(int a); // 나이를 설정하는 public 함수
};

// 나이 반환 함수 정의
int Dog::getAge() {
    return age; // age를 반환
}

// 나이 설정 함수 정의
void Dog::setAge(int a) {
    age = a; // age에 매개변수 a를 할당
}

int main() {
    Dog *dp = new Dog; // Dog 객체를 동적으로 할당

    // 동적 메모리 할당 후 나이를 설정
    dp->setAge(5); // 동적 할당된 Dog 객체의 나이를 5로 설정
    std::cout << "메모리에 할당된 값은 " << dp->getAge() << "입니다."; // 나이 출력

    delete dp; // 동적으로 할당된 메모리 해제
    return 0; // 프로그램 종료
}
```

### 요약

- `Dog` 클래스는 개의 나이를 저장하고 설정하는 메서드를 가지고 있습니다.
- `main` 함수에서는 동적으로 `Dog` 객체를 할당하고, 나이를 설정한 후 출력합니다.
- 메모리 해제를 통해 메모리 누수를 방지하고 있습니다.

이 코드는 동적 메모리 할당을 활용하여 객체를 생성하고 관리하는 기본적인 예제입니다. 

 

 

주어진 C++ 코드에서 `const` 키워드를 추가할 수 있는 부분을 설명하겠습니다. `const`는 객체의 상태를 변경하지 않는 멤버 함수에 사용되며, 이를 통해 코드의 의도를 명확히 하고, 불필요한 변경을 방지할 수 있습니다.

### 수정할 부분

1. **`getAge()` 함수**: 이 함수는 개의 나이를 반환하는 함수로, 객체의 상태를 변경하지 않으므로 `const`로 지정해야 합니다.

2. **`setAge()` 함수**: 이 함수는 객체의 상태를 변경하는 함수이므로 `const`로 지정할 필요가 없습니다.

3. **`main` 함수의 반복문**: 반복문에서 사용하는 인덱스 변수 `i`는 `const`로 지정할 필요가 없습니다. 하지만, `for` 루프의 범위 기반 반복문을 사용하여 더 안전하게 사용할 수 있습니다.

### 수정된 코드

아래는 `const` 키워드를 추가한 수정된 코드입니다.

```cpp
#include <iostream>
using namespace std;

class Dog {
private:
    int age; // 개의 나이
public:
    int getAge() const; // 나이를 반환하는 함수에 const 추가
    void setAge(int a); // 나이를 설정하는 함수
};

// 나이 반환 함수 정의
int Dog::getAge() const {
    return age; // age를 반환
}

// 나이 설정 함수 정의
void Dog::setAge(int a) {
    age = a; // age에 매개변수 a를 할당
}

int main() {
    Dog *dp; // Dog 객체 포인터 선언
    dp = new Dog[10]; // 객체 배열 할당

    // 메모리 할당 확인 (C++에서는 new가 실패하면 예외를 발생시킴)
    if (!dp) {
        std::cout << "메모리 할당이 되지 않았습니다.";
        return 1; // 프로그램 종료
    }

    // 각 Dog 객체의 나이를 설정
    for (int i = 0; i < 10; i++) {
        dp[i].setAge(i); // i번째 객체의 나이를 i로 설정
    }

    // 각 Dog 객체의 나이를 출력
    for (int i = 0; i < 10; i++) {
        std::cout << i << "번째 객체의 나이는 " << dp[i].getAge() << " 입니다." << std::endl;
    }

    delete[] dp; // 동적으로 할당된 메모리 해제
    return 0; // 프로그램 종료
}
```

### 요약

- `getAge()` 함수에 `const` 키워드를 추가하여 이 함수가 객체의 상태를 변경하지 않음을 명시했습니다.
- `setAge()` 함수는 상태를 변경하는 함수이므로 `const`를 추가하지 않았습니다.

이러한 수정은 코드의 가독성을 높이고, 객체 지향 프로그래밍의 원칙을 준수하는 데 도움이 됩니다. 

 

#include <iostream>
class Dog {
private:
int age;
public:
int getAge();
void setAge(int a);
};
int Dog::getAge()
{
return age;
}
void Dog::setAge(int a)
{
age = a;
}
int main()
{
Dog* dp;
dp = new Dog; // Dog *dp=new Dog
if (!dp) {
std::cout << "메모리할당 불가!";
return 1;
}
happy.setAge(3);
std::cout << happy.getAge();
dp->setAge(5);
std::cout << "메모리에 할당된 값은 "
<< dp->getAge() << "입니다.";
delete dp;
return 0;
}

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using std::cout;
class Cat {
private: //생략가능
int age;
std::string name;
public:
Cat(int age, std::string n) {
this->age = age;
name=n;
cout << name << "고양이 객체가 만들어졌어요.\n";
}
~Cat() { cout << name << "객체 바이\n"; };
int getAge() const;
std::string getName()const;
void setAge(int age);
void setName(std::string pName);
void meow() const;
};
int Cat::getAge() const {
return age;
}
void Cat::setAge(int age) {
this->age = age;
}
void Cat::setName(std::string pName) {
name=pName;
}
std::string Cat::getName() const {
return name;
}
void Cat::meow() const {
cout << name << "고양이가 울어요\n";
}
int main() {
Cat nabi(1, "나비"), yaong(1, "야옹"), * pNabi;
cout << nabi.getName() << " 출생 나이는 " << nabi.getAge() << "살이다.\n";
cout << yaong.getName() << " 출생 나이는 " << yaong.getAge() << "살이다.\n";
pNabi = &nabi;
cout << pNabi->getName() << " 출생 나이는 " << pNabi->getAge() << "살이다.\n";
nabi.setName("Nabi");
nabi.setAge(3);
cout << nabi.getName() << " 나이는 " << nabi.getAge() << "살이다.\n";
yaong.meow();
nabi.meow();
return 0;
}

 

'인덕대 C++-출처 smile han' 카테고리의 다른 글

c++11주차  (0) 2024.11.11
11주차예습  (0) 2024.11.10
10주차 예습  (0) 2024.11.02
9주차  (0) 2024.10.28
C++9주차 예습  (0) 2024.10.27