내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
목차
클래스 정의 형식
class는 클래스를 정의하는 키워드이고, Stack은 클래스의 이름이며, {}는 클래스의 본문입니다. 정의 끝의 세미콜론은 생략되지 않습니다. 클래스 본문에 있는 내용을 클래스의 멤버라고 합니다. 클래스에 있는 변수를 클래스의 속성 또는 멤버 변수라고 합니다. 클래스의 메서드 또는 멤버 함수라고 합니다.
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
- //成员变量
- int* a;
- int top;
- int capacity;
- //成员函数
- void Push()
- {
-
- }
- void Pop()
- {
-
- }
- };//分号不能省略
- int main()
- {
-
-
- return 0;
- }
- //为区分成员变量,一般前面加_
- //成员变量
- int* _a;
- int _top;
- int _capacity;
C++는 캡슐화를 구현하는 방법으로, 클래스를 사용하여 개체의 속성과 메서드를 결합하여 개체를 더욱 완벽하게 만들고 액세스 권한을 통해 외부 사용자에게 해당 인터페이스를 선택적으로 제공합니다.
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
-
- ///
-
- void Push()
- {
-
- }
- //Push 没给限定符 class默认私有 private
- ///
- public:
- void Pop()
- {
-
- }
- int Swap()
- {
-
- }
- //Pop和Swap 被public修饰,直到下一个限定符出现之前都为公有
- ///
- protected:
- int add();
- //add 被public修饰,直到下一个限定符出现之前都为保护
- /// /
-
- private:
-
- int* _a;
- int _top;
- int _capacity;
- //成员变量被private修饰,直到}结束都为私有
- };
- int main()
- {
- Stack st;
- //公有可以访问
- st.Pop();
- st.Swap();
- //私有不可访问
- st._top;
-
-
-
- return 0;
- }
추가 참고 사항:
클래스는 새 범위를 정의합니다. 클래스의 모든 멤버는 클래스 범위에 있습니다. 클래스 외부에서 멤버를 정의하는 경우 ::scope 연산자를 사용하여 해당 멤버가 속한 클래스 범위를 표시해야 합니다.
클래스 도메인은 컴파일의 검색 규칙에 영향을 미칩니다. 다음 프로그램의 Init가 클래스 도메인 Stack을 지정하지 않으면 컴파일러는 컴파일 중에 Init를 전역 함수로 처리합니다. 클래스 도메인에서.
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
-
- public:
- void Init(int x, int y);
-
- };
- void Stack::Init(int x, int y)
-
- {
- _top = x;
- _capacity = y;
- }
- int main()
- {
-
- return 0;
- }
알아채다:
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
- //声明
-
- int* _a;
- int _top;
- int _capacity;
-
- };
-
- int main()
- {
-
- Stack::_top = 2024;
- //编译器报错,_top只是声明,并未实例化
-
- return 0;
- }
-
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Stack
- {
-
-
- //声明
- int* _a;
- int _top;
- int _capacity;
-
- };
-
- int main()
- {
-
-
- Stack st;
- st._top=2024;
- //Stack实例化出st,系统已经给st分配内存了,可以存储数据,编译通过
-
- return 0;
- }
-
-
메모리 정렬 규칙
- class A
- {
- public:
- void Print()
- {
- cout << _ch << endl;
- }
- private:
- char _ch;
-
- int _i;
- };
- //_ch 是一个字节,默认对齐数是4,最大对齐数是4,所以开辟4个字节用来存在_ch
- // _i是4个字节,默认对齐数是4,最大对齐数是4,所以开辟4个字节用来存储_i
- class B
- {
- public:
- void Print()
- {
- //。。。
- }
-
-
- };
- class B
- {
-
-
- };
- //B和C里面没有存储任何成员变量,只有一个函数,可成员函数不存对象里面
- // 按理来说是0,但是结构体怎么会没大小,为表示对象存在C++对这种规定大小为1,为了占位标识对象存在
컴파일러가 컴파일된 후 클래스의 멤버 함수는 기본적으로 이 포인터라고 하는 형식 매개변수의 첫 번째 위치에 현재 클래스에 대한 포인터를 추가합니다.
예를 들어 Date 클래스의 Init 프로토타입은 void Init(Date * const this, int year, int Month, int day)입니다. 클래스의 멤버 함수에서 멤버 변수에 액세스할 때 this 포인터를 통해 본질에 액세스합니다. 예를 들어 Init 함수의 _year, this->_year=year입니다.
원기:
- class Date
- {
- void Print()
- {
-
- cout << _year << "n" << _month << "n" << _day << endl;
- }
- void Init( int year, int month,int day)
- {
- _year = year;
- _month = month;
- _day = day;
-
- }
-
- private:
- int _year;
- int _month;
- int _day;
-
- };
-
- Date d1;
- d1.Init(2024,7,10);
-
- d1.Print();
- Date d2;
-
- d2.Init(2024, 7, 9);
- d2.Print();
-
실제 프로토타입
- class Date
- {
- void Init(Date* const this,int year, int month,int day)
-
- {
- this->_year = year;
- this->_month = month;
- this->_day = day;
-
- }
- void Printf(Date* const this)
-
- {
-
- cout << this->_year << "n" <<this-> _month << "n" << this->_day << endl;
- }
- private:
- int _year;
- int _month;
- int _day;
-
- };
- Date d1;
- d1.Init(&d1,2024,7,10);
- d1.Print(&d1);
-
- Date d2;
- d2.Init(&d2,2024, 7, 9);
- d2.Print();
C++에서는 이 포인터를 실제 매개변수와 형식 매개변수 위치에 쓰는 것이 허용되지 않는다고 규정하고 있지만(컴파일러가 이를 처리합니다) 함수 본문에서는 이 포인터를 명시적으로 사용할 수 있지만 이 포인터는 수정할 수 없습니다. 이 포인터가 가리키는 콘텐츠는
이 포인터는 스택에 저장됩니다
기본 멤버 함수는 사용자가 명시적으로 정의하지 않고 컴파일러에 의해 자동으로 생성되는 멤버 함수를 말합니다.
생성자는 특별한 멤버 함수입니다. 생성자의 이름은 생성자이지만 생성자의 주요 내용은 객체를 생성하기 위해 공간을 여는 것이 아닙니다(우리가 일반적으로 사용하는 로컬 객체는 생성되는 공간입니다). 스택 프레임이 생성될 때 열림)), 객체가 인스턴스화될 때 객체가 초기화됩니다. 생성자의 본질은 이전에 Stack 및 Date 클래스에서 작성한 Init 함수의 함수를 대체하는 것입니다. 생성자의 자동 호출은 Init 함수를 완벽하게 대체합니다.
생성자의 특징:
- class Date
- {public:
- //1.无参构造函数
- Date()
- {
- _year = 1;
- _month = 1;
- _day = 1;
- }
- //2.带参构造函数
- Date(int year, int month, int day)
- {
- _year = year;
- _month = month;
- _day = day;
- }
-
-
- //3.全缺省构造函数
- Date(int year = 1, int month = 1, int day = 1)
- {
- _year = year;
- _month = month;
- _day = day;
- }
- private:
- int _year;
- int _month;
- int _day;
-
- };
매개변수 없는 생성자, 전체 기본 생성자, 생성자를 작성하지 않을 때 컴파일러가 기본적으로 생성하는 생성자를 모두 기본 생성자라고 합니다. 그러나 이 세 가지 중 하나만 존재할 수 있으며 동시에 존재할 수는 없습니다. 매개변수 없는 생성자와 전체 기본 생성자는 함수 오버로드를 구성하지만 호출할 때 모호성이 있습니다.기본 생성자는 기본적으로 컴파일러에 의해 생성되는 생성자일 뿐만 아니라 매개 변수가 없는 생성자이며 전체 기본 생성자도 기본 생성자이므로 매개 변수를 전달하지 않고도 호출할 수 있습니다.
우리는 이를 작성하지 않습니다. 기본적으로 컴파일러에 의해 생성된 생성자는 내장 유형 멤버 변수의 초기화에 대한 요구 사항이 없습니다. 즉, 초기화 여부는 확실하지 않으며 컴파일러에 따라 다릅니다.
- //text.cpp
- #include<iostream>
- using namespace std;
- typedef int STDataType;
- class Stack
- {
- public:
- Stack(int n = 4)
- {
- _a = (STDataType*)malloc(sizeof(STDataType) * n);
- if (nullptr == _a)
- {
- perror("malloc申请失败");
- }
- _capacity = n;
- _top = 0;
- }
-
- private:
- STDataType* _a;
- size_t _capacity;
- size_t _top;
- };
- //两个Stack实现队列
- class MyQueue
- {
- private:
- int size;
- Stack pushst;
- Stack popst;
- };
-
- int main()
- {
-
- MyQueue my;
-
-
- return 0;
- }
-
C++에서는 유형을 사용자 정의 유형과 내장 유형(기본 유형)으로 나눕니다. 내장 유형은 int/char/double/pointer 등과 같이 언어에서 제공하는 기본 데이터 유형입니다. 사용자 정의 유형은 class/struct와 같은 키워드를 사용하여 직접 정의하는 유형입니다.여기의 생성자는 자동으로 초기화되며 VS는 내장 유형 크기도 초기화합니다. 컴파일러마다 초기화 값이 다르며 C++에서는 이를 지정하지 않습니다.
사용자 정의 유형 멤버 변수의 경우 이 멤버 변수의 기본 생성자를 호출하여 초기화해야 합니다.이 멤버 변수에 기본 생성자가 없으면 오류가 보고됩니다. 이 멤버 변수를 초기화하려면 초기화 목록을 사용하여 이를 해결해야 합니다.
요약: 대부분의 경우 생성자를 직접 구현해야 합니다. 몇 가지 경우에는 MyQueue와 유사하며 Stack에 기본 생성자가 있으면 MyQueue가 자동으로 생성되어 사용될 수 있습니다.
- ~Stack()
- {
- free(_a);
- _a = nullptr;
- _top = _capacity = 0;
- }
소멸자의 특성:
1. 소멸자 이름은 클래스 이름 앞에 ~ 문자를 추가하는 것입니다.
2. 매개변수도 없고 반환 값도 없습니다(생성자와 일치).
3. 클래스에는 소멸자가 하나만 있을 수 있습니다.정의가 표시되지 않으면 시스템은 자동으로 기본 소멸자를 생성합니다.
4. 객체 선언 주기가 끝나면 시스템은 자동으로 소멸자를 호출합니다.
5. 생성자와 유사하게 컴파일러에 의해 자동으로 생성된 소멸자를 작성하지 않으며 내장 유형 멤버를 처리하지 않습니다. 사용자 정의 유형 멤버는 다른 소멸자를 호출합니다.
6. 또한 소멸자를 표시할 때 사용자 정의 유형 멤버의 소멸자도 호출된다는 점에 유의해야 합니다. 이는 상황에 관계없이 사용자 정의 유형 멤버의 소멸자가 자동으로 호출된다는 의미입니다.
- //text.cpp
- #include<iostream>
- using namespace std;
- typedef int STDataType;
- class Stack
- {
- public:
- Stack(int n = 4)
- {
- _a = (STDataType*)malloc(sizeof(STDataType) * n);
- if (nullptr == _a)
- {
- perror("malloc申请失败");
- }
- _capacity = n;
- _top = 0;
-
-
- }
-
- ~Stack()
- {
- free(_a);
- _a = nullptr;
- _top=_capacity=0;
- }
- private:
- STDataType* _a;
- size_t _capacity;
- size_t _top;
-
- };
- //两个Stack实现队列
- class MyQueue
- {public:
- //编译器默认生成MyQueue的构造函数调用了Stack的构造,完成了两个成员的初始化
- //编译器默认生成MyQueue的析构函数调用了Stack的析构,释放了Stack内部的资源
- //显示写析构也会调用Stack的析构
- ~MyQueue()
- {
- cout << "~MyQueue" << endl;
- }
- private:
-
- Stack pushst;
- Stack popst;
-
- };
-
-
- int main()
- {
-
- MyQueue my;
-
-
- return 0;
- }
MyQueue의 소멸자는 아무 작업도 수행하지 않지만 C++에서는 메모리를 해제하기 위해 다른 소멸자가 호출되도록 규정합니다.
리소스가 요청되지 않으면 소멸자를 작성할 필요가 없으며, Date와 같이 컴파일러에서 생성된 기본 소멸자를 직접 사용할 수 있습니다. 생성된 기본 소멸자를 사용할 수 있는 경우 소멸자를 명시적으로 작성할 필요가 없습니다. MyQueue 등이 있는데, 소멸시에는 반드시 소멸자를 직접 작성해야 합니다. 그렇지 않으면 Stack 등의 리소스 누수 현상이 발생하게 됩니다.
-
-
- bool operator<(Date d1, Date d2)
- {
-
- }
- bool operator==(Date d1,Date d2)
- {
- return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
- }
- //text.cpp
- #include<iostream>
- using namespace std;
-
- class Date
- {
- public:
- Date(int year, int month, int day)
- {
- _year= year;
- _month = month;
- _day = day;
-
- }
-
-
-
- int _year;
- int _month;
- int _day;
-
- };
-
- bool operator<(Date d1, Date d2)
- {
-
- }
- bool operator==(Date d1,Date d2)
- {
- return d1._year == d2._year && d1._month == d2._month && d1._day == d2._day;
- }
- int main()
- {
-
- Date d1(2024, 7, 10);
- Date d2(2024,7,9);
- //两种用法都可以
- d1 == d2;
- operator==(d1 , d2);
- return 0;
- }