한성대학교 김설현교수님 강의내용을 바탕으로 작성함
동적 메모리 할당프로그램 실행 도중 필요한 만큼의 메모리를 할당하는 것이다.new연산자를 이용해 동적으로 메모리를 할당하며, heap에 저장된다.
int *p = new int;
new연산자를 사용해 할당한 메모리는 영구적이며, delete를 사용하여 제거하고 포인터변수에 NULL을 대입해야한다.
int *p = new int;
delte p;
p = NULL;
int *p = new int[size];
delete [ ] p;
p = NULL;
동적 객체 생성과 접근
아래의 구문을 사용하여 heap에 동적으로 객체 생성 가능하다.
Circle* cp = new Circle;
Circle* cp = new Circle(2);
포인터를 통한 객체 멤버에 접근하기 위해서는 점(.)이나 화살표(->)연산자를 사용한다.
cp->getRadius()
(*cp).getRadius()
this 포인터
객체 자신을 가리킨다.
set()함수나 매개변수 있는 생성자에서 종종 매개변수와 데이터필드에 같은 이름을 사용할 때 사용한다.
Circle::Circle(double radius)
{
this->radius = radius; //this->radius 는 본래의 radius이고 오른쪽의 radius는 받는 값
}
소멸자
생성자의 반대이며 생성자와 동일한 이름을 갖지만 앞에(~)가 붙어야 한다.
기본적으로 모든 클래스에는 기본 소멸자가 포함된다.
사용자의 요구 동작을 수행하기 위해 구현하는 경우가 있다.
Circle.h
#ifndef CIRCLE_H
#define CIRCLE_H
class Circle {
public:
Circle();
Circle(double);
~Circle(); // 소멸자
double getArea();
double getRadius();
void setRadius(double);
static int getNumberOfObjects();
private:
double radius;
static int numberOfObjects;
};
#endif
Circle.cpp
#include "Circle.h"
int Circle::numberOfObjects = 0; //정적멤버 초기화
Circle::Circle()
{
radius = 1;
numberOfObjects++;
}
Circle::Circle(double radius)
{
this->radius = radius;
numberOfObjects++;
}
Circle::~Circle() //소멸자
{
numberOfObjects--;
}
double Circle::getArea()
{
return radius * radius * 3.14159;
}
double Circle::getRadius()
{
return radius;
}
void Circle::setRadius(double radius)
{
this->radius = (radius >= 0) ? radius : 0;
}
int Circle::getNumberOfObjects()
{
return numberOfObjects;
}
main.cpp
#incldue<iostream>
#include"Circle.h"
using namespace std;
int main()
{
Circle* pCircle1 = new Circle();
Circle* pCircle2 = new Circle(5.0);
Circle* pCircle3 = new Circle(2);
cout << "원의 개수: " << Circle::getNumberOfObjects() << endl;
delete pCircle1;
pCircle1 = NULL;
cout << "원의 개수: " << Circle::getNumberOfObjects() << endl;
system("pause");
return 0;
}
소멸자가 없었으면 삭제후에도 3이 나온다.
복사 생성자
동일 클래스의 다른 객체의 데이터를 초기화 된 객체를 생성하는데 사용한다.
Circle circle1 (5);
Circle circle2 (circle1);
Circle circle3 = circle1;
Circle 클래스의 복사 생성자의 시그니쳐는 아래와 같다.
Circle (const Circle&)
복사생성자를 정의하지 않으면 기본 복사 생성자가 각 클래스에 제공된다.
기본 복사 생성자는 얕은 복사를 수행한다.
얕은 복사 vs 깊은 복사
얕은 복사 : 포인터의 주소가 복사된다.
깊은 복사 : 포인터의 내용이 복사된다.
즉, 얕은 복사를 하면 복사후 원본을 변경하면 복사본도 같이 변경된다.
얕은복사
Course.h
#ifndef CIRCLE_H
#define CIRCLE_H
class Course
{
public:
Course(const string& courseName, int capacity);
~Course();
void addStudent(const string& name);
string* getStudents() const;
int getNumberOfStudents() const;
private:
string courseName;
string* students;
int numberOfStudents;
int capacity;
};
#endif
Course.cpp
#include "Course.h"
Course::Course(const string& courseName, int capacity)
{
numberOfStudents = 0;
this->courseName = courseName;
this->capacity = capacity;
students = new string[capacity];
}
Course::~Course()
{
//delete[] students; //얕은복사에서 에러
}
void Course::addStudent(const string& name)
{
students[numberOfStudents] = name;
numberOfStudents++;
}
string* Course::getStudents() const
{
return students;
}
int Course::getNumberOfStudents() const
{
return numberOfStudents;
}
main.cpp
#include <iostream>
#include "Course.h"
using namespace std;
int main()
{
Course course1("C++ Programming", 10);
Course course2(course1);
course1.addStudent("Peter Pan"); // Add a student to course1
course2.addStudent("Lisa Ma"); // Add a student to course2
cout << "students in course1: " << course1.getStudents()[0] << endl;
cout << "students in course2: " << course2.getStudents()[0] << endl;
system("pause");
return 0;
}
깊은복사
Course.h
#ifndef CIRCLE_H
#define CIRCLE_H
class Course
{
public:
Course(const string& courseName, int capacity);
~Course();
Course(const Course&); //복사생성자
void addStudent(const string& name);
string* getStudents() const;
int getNumberOfStudents() const;
private:
string courseName;
string* students;
int numberOfStudents;
int capacity;
};
#endif
Course.cpp
#include "Course.h"
Course::Course(const string& courseName, int capacity)
{
numberOfStudents = 0;
this->courseName = courseName;
this->capacity = capacity;
students = new string[capacity];
}
Course::~Course()
{
delete[] students; //에러안남
}
//복사생성자
Course::Course(const Course& course)
{
courseName = course.courseName;
numberOfStudents = course.numberOfStudents;
capacity = course.capacity;
students = new string[capacity];
for (int i = 0; i < numberOfStudents; i++)
students[i] = course.students[i];
}
void Course::addStudent(const string& name)
{
students[numberOfStudents] = name;
numberOfStudents++;
}
string* Course::getStudents() const
{
return students;
}
int Course::getNumberOfStudents() const
{
return numberOfStudents;
}
main.cpp
#include <iostream>
#include "Course.h"
using namespace std;
int main()
{
Course course1("C++ Programming", 10);
Course course2(course1);
course1.addStudent("Peter Pan"); // Add a student to course1
course2.addStudent("Lisa Ma"); // Add a student to course2
cout << "students in course1: " << course1.getStudents()[0] << endl;
cout << "students in course2: " << course2.getStudents()[0] << endl;
system("pause");
return 0;
}
'개발 > C++' 카테고리의 다른 글
15장 상속과 다형성 (0) | 2021.12.09 |
---|---|
14장 연산자 오버로딩 (0) | 2021.12.09 |
13장 파일 입력과 출력 (0) | 2019.05.21 |
12장 템플릿, 벡터, 스택 (0) | 2019.05.13 |
11장 포인터와 동적 메모리 관리(전) (0) | 2019.05.08 |
10장 객체 지향 개념 (0) | 2019.02.11 |
9장 객체와 클래스 (0) | 2019.01.19 |
8장 다차원 배열 (0) | 2019.01.16 |
댓글