Chat GPT . new연산자를 사용하는 언어를 설명해줘
1. C++ : 객체를 동적으로 생성할 때 사용됩니다.
MyClass* obj = new MyClass();
여기서 MyClass의 인스턴스가 동적으로 할당되고, obj 포인터가 그 주소를 가리킵니다. 사용이 끝난 후에는 delete 연산자를 사용하여 메모리를 해제해야 합니다.
2. Java : 객체를 생성합니다.
MyClass obj = new MyClass();
Java에서는 가비지 컬렉터가 메모리를 자동으로 관리하므로, 명시적으로 메모리를 해제할 필요는 없습니다.
3. C# : C#에서도 Java와 유사하게 new 키워드를 사용합니다.
MyClass obj = new MyClass();
C# 역시 가비지 컬렉션을 사용하여 메모리를 자동으로 관리합니다.
4. JavaScript : 생성자 함수를 통해 객체를 생성합니다.
let obj = new MyClass();
이 경우 MyClass는 생성자 함수이며, obj는 그 인스턴스입니다.
- 선택 단어 일괄 교체하기 : ctrl + h
1. const 변수
: 변수에 const라는 키워드를 사용하여 상수(constant)의 의미를 갖게 하여 그 내용을 변경할 수 없게 함
▷ 변수를 상수로 만드는 방법
#define IN 1 // 컴파일 전에 IN을 찾아서 1로 바꿈
#include <iostream>
int main()
{
const int x = 2; // 변수 x는 항상 2, 변경 불가, 초깃값 지정해야
int const y = 3; // 비추, const는 자료형 앞에 씀
const int z{ 4 }; // Uniform initialization, C++11, z{}
constexpr int a = 5; //C++11부터 가능, compile-time constant
//x = 2; //변경 불가
std::cout << IN << x << y << z << a;
return 0;
}
- const 멤버
- const형 멤버함수는 해당 멤버변수를 변경하는 치환연산을 수행할 수 없다.
- const로 지정된 함수에서는 멤버변수의 값을 변경할 수 없다.
- const함수는 const함수만 호출 할 수 있다.
일반 멤버함수에는 접근할 수 없다. - 생성자와 소별자에서는 const 사용 불가능
- const형을 선언하려면 멤버변수는 형 앞에 const를, 멤버함수는 함수의 괄호 다음에 const를 추가한다.
int getAge() const
{
return age;
}
▷ const형 멤버함수
#include <iostream>
class Dog {
int age; //private 생략함
public:
int getAge() const;
void setAge(int a) { age = a; } //setAge는 수를 받아서 계속 변하기때문애 const 사용 불가능
void view() { std::cout << "나는 view"; }
};
int Dog::getAge() const
{
view(); // 오류 ① const멤버함수라 위에 view()도 const여야 한다.
return (++age); // 오류 ② ++ 때문에 오류 발생 ++없애면 정상작동
}
int main()
{
Dog happy;
happy.setAge(5);
std::cout << happy.getAge();
return 0;
}
↓
#include <iostream>
class Dog {
int age; //private 생략함
public:
int getAge() const;
void setAge(int a) { age = a; } //setAge는 수를 받아서 계속 변하기때문애 const 사용 불가능
void view() const { std::cout << "나는 view"; }
};
int Dog::getAge() const
{
view(); // 오류 ① const멤버함수라 위에 view()도 const여야 한다.
return (age); // 오류 ② ++ 때문에 오류 발생 ++없애면 정상작동
}
int main()
{
Dog happy;
happy.setAge(5);
std::cout << happy.getAge();
return 0;
}
- const 객체
- 객체가 const로 지정되면 해당 객체에 초기화된 데이터는 변경할 수 없다.
- const로 지저오딘 멤버함수만 호출 가능
- 클래스 명 앞에 const 추가
const Dog happy;
▷ const 객체
#include <iostream>
class Dog {
int age;
public:
Dog(int a) { age = a; }
int getAge() const;
void setAge(int a) { age = a; }
void view() const
{
std::cout << "나는 view\n";
}
};
int Dog::getAge() const
{
view();
return (age);
}
int main()
{
const Dog happy(5); //const 객체
happy.setAge(7); // happy가 const객체라 변경 불가능함. const를 지우거나 이 줄을 없애면 오류 해결
std::cout << happy.getAge();
return 0;
}
2. 포인터
: 포인터를 이용하게 되면 기계어나 어셈블리 언어처럼 메모리의 주소를 이용해 메모리의 내용을 직접 접근할 수 있음
- 포인터 사용하는 경우
- call by reference로 함수로부터 한 개 이상의 값을 리턴할 때
- 함수들 간에 배열이나 문자열을 전달할 때
- 배열 조작을 쉽게 할 때
- 연결 리스트나 이진트리 등 복잡한 자료 구조를 만들 때
- 메모리를 동적으로 할당할 때
- 포인터와 주소
: 메모리에는 위치를 구분하기 위해 순서대로 번호가 붙어있는데 이것을 메모리의 주소, 번지, address라고 함
int sum=0;
- 변수를 초기화하면서 선언하면, int형이므로 4바이트 메모리 공간이 확보되고 초기값으로 0이 할당됨
- sum변수가 실제로 할당된 메모리의 주소를 알고 싶다면 &연산자를 사용하여 &sum이라고 하면 변수가 기억되어 있는 메모리 번지를 알 수 있음
- 메모리의 주소를 저장하려면 일반 변수가 아닌 포인터를 사용
- 포인터라고만 해도 되지만 주소를 저장하는 변수이므로 포인터 변수라고도 함
- 포인터 선언 * , 참조 연산자 *
- 포인터도 변수라 사용하기 전에 선언해야 함
- 자료형과 변수명 사이에 구두점 * 쓰면 됨
#include <iostream> // C++ 표준 입출력 라이브러리를 포함합니다.
int main() // 프로그램의 시작점인 main 함수를 정의합니다.
{
int x = 1; // 정수형 변수 x를 선언하고 1로 초기화합니다.
int *px = &x; // x의 주소를 가리키는 포인터 px를 선언하고 x의 주소를 할당합니다.
// x의 값, x의 주소, 포인터 px가 가리키는 값(즉, x의 값)을 출력합니다.
std::cout << x << " " << &x << " " << *px;
return 0; // 프로그램을 정상적으로 종료합니다.
}
3. 동적 메모리 할당(new, delete)
▶ 동적 메모리 사용 이유
#include <iostream>
int main()
{
int x = 1; // 정적 할당
int* px = new int(5); //동적으로 할당
delete px;
return 0;
}
● new와 delete
- new는 메모리를 힙에 동적으로 할당하고, 할당된 메모리에 대한 주소를 반환하는 연산자이다.
- malloc() 함수와 마찬가지로, 요구한 만큼의 메모리가 충분하지 않으면 new는 null포인터를 반환한다. - delete는 free()함수와 마찬가지로, 더 이상 필요 없는 메모리를 해제한다.
- 장점
- 기본 자료형
- delete
- 배열
- delete
▷ 하나의 정수에 대한 메모리 할당과 해제 : 정적 vs 동적
#include <iostream>
int main()
{
int* pi = new int; // 메모리 할당. 정수형 자료를 저장하기 위한 4바이트 공간항당
//pi는 첫번째 공간의 주소
int x;
if (!pi) { // pi==0, 널 포인터인지 확인. !pi가 거짓인가? pi가 0인가?
std::cout << "메모리할당이 되지 않았습니다.";
return 1; //비정상 종료시 리턴값
}
*pi = 100; //주소의 값으로 100을 할당
x = 10;
std::cout << "동적메모리=" << *pi << ", x=" << x;
delete pi; // 메모리 해제
return 0; // 정상 종료시 리턴값
}
▷ 동적메모리 할당(필요한 만큼의 메모리만 실행시 할당)
#include <iostream>
#include <stdlib.h> //exit(1)사용을 위한 헤더
int main()
{
int i, n;
int *num;
std::cout << "몇 개의 숫자를 입력하시겠습니까==";
std::cin >> i; //사용자로부터 입력받은 숫자를 i에 저장
num = new int[i]; // i개의 정수를 저장할 동적 배열 할당
if (num == NULL) exit(1); //종료. 메모리 할당 실패 시 종료
for (n = 0; n < i; n++)
{
std::cout << "숫자를 입력하십시오 : ";
std::cin >> num[n];
}
std::cout << "당신이 입력한 숫자는: ";
for (n = 0; n < i; n++)
std::cout << num[n] << ", ";
delete[] num; // 동적 메모리 해제
return 0;
}
▷ 객체 동적할당
#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;
}
dp->setAge(5);
std::cout << "메모리에 할당된 값은 " << dp->getAge() << "입니다."; // 포인터 객체는 -> 로 접근한다.
delete dp;
return 0;
}
▷ 배열객체 동적 할당
#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[10]; // 객체배열 할당
// Dog *dp=new Dog[10];
if (!dp) {
std::cout << "메모리할당이 되지 않았습니다.";
return 1;
}
for (int i = 0; i < 10; i++) // C++에서는 가능
dp[i].setAge(i);
for (int i = 0; i < 10; i++)
std::cout << i << "번째 객체의 나이는 " << dp[i].getAge() << " 입니다. " << std::endl;
delete[]dp;
return 0;
}
▷ cat클래스에 const 추가하고 주석 달기. 동적 메모리를 할당하는 이유와 방법
#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++' 카테고리의 다른 글
12. 상속 (inheritance) (2) | 2024.11.19 |
---|---|
11. 함수 중첩, 디폴트 인자 (0) | 2024.11.12 |
7. 객체와 멤버, 생성자/소멸자, this 포인터 (0) | 2024.10.29 |
6. 접근 속성 클래스와 객체 만들기 (2) | 2024.10.15 |
5. 객체지향 프로그래밍 (0) | 2024.10.08 |