cx_oracle

파이썬에서 oracle DB에 쿼리를 날릴려면 cx_oracle을 설치해야한다.(pip install cx_oracle)

 

Oracle Service Class
import cx_Oracle
import os
from cx_Oracle import Connection, Cursor


class OracleService:
    def __init__(self, query: str):
        self.result: list = []
        self.cursor: Cursor = self.init_env().cursor()
        self.get_result(query)

    def init_env(self) -> Connection:
        os.environ["NLS_LANG"] = ".AL32UTF8"
        dsn_tns = cx_Oracle.makedsn('ip', '1521', service_name='service_name')
        return cx_Oracle.connect(user=r'user', password='password', dsn=dsn_tns)

    def get_result(self, query) -> None:
        self.cursor.execute(query)
        dict_temp: dict = {}
        for (RPICU, RPTAX, RPALPH, RPDC, RPZ5DEBITAT, RPDL02, RPRMK) in self.cursor:
            dict_temp['RPICU'] = RPICU
            dict_temp['RPTAX'] = RPTAX.strip()
            dict_temp['RPALPH'] = RPALPH.strip()
            dict_temp['RPDC'] = RPDC.strip()
            dict_temp['RPZ5DEBITAT'] = str(RPZ5DEBITAT).strip()
            dict_temp['RPDL02'] = RPDL02.strip()
            dict_temp['RPRMK'] = RPRMK.strip()
            self.result.append(dict_temp)

1. 간단하게 init_env 메서드를 활용해서 Connection을 만든다.

  - os.envrion을 지정해줘야 한글이 깨지지 않는다.

 

2. get_result 메서드를 이용해서 쿼리를 날리고 결과를 result에 담는다.

 

너무 심플하다.

 

Django HttpResponse
    query = "select *  from 오라클 TABLE"
    service = OracleService(query)
    return HttpResponse(content=json.dumps(service.result), content_type='application/json')

1. django에서 httpResponse를 날릴때 json.dumps를 이용해서 json 데이터로 response를 보낼 수 있도록하자.

 

ALU(Arithmetic Logic Unit)

CPU는 덧셈이나 뺄셈과 같은 연산의 주체다 이건 누구나 다 아는 사실 하지만 좀 더 깊게 들어가면 ALU라는 녀석이 실제 연산을 담당한다. ALU 연산은 크게 두가지로 나뉜다 하나는 덧셈이나 뺄셈 같은 산술연산, 하나는 AND와 OR 같은 논리 연산이다.

 

 

Control Unit

프로그램을 컴파일하면 실행파일이 되고 이 실행파일에는 CPU에게 일을 시키는 명령어가 저장되어 있다.

이 명령어가 CPU 내부의 ALU로 전송되었다고 가정하자. 명령어는 다 0과 1로 구성되어있다(당연하다 컴퓨터는 0과 1밖에 모르니) 32비트 명령어라면 "00001111 00001111 00001111 00001111"와 같이 구성되어 있을 것이다.

과연 ALU가 0과 1로 구성되어있는 명령어를 이해할 수 있나? 못한다 ALU는 연산만 하니깐 이명령어를 해석해주는 놈이 바로 컨트롤 유닛이다.

 

 

레지스터(Register)

명령어가 CPU로 들어왔다고 가정하자. 덧셈 명령어 그리고 덧셈에 필요한 피연산자. 명령어는 컨트롤 유닛으로 피연산자는 ALU로 보내면된다. 하지만 ALU나 컨트롤 유닛이 지금 다른 명령어를 해석하고 있다면?? CPU 내부에 데이터를 저장해두고 CPU가 필요할 때 직접 가져다 쓰면 좋을 것 같다. 그렇다 CPU 내부의 조그마한 메모리 공간을 레지스터라고 한다.(연산할때 일일이 메모리에서 가져다가 연산하면 속도가 개판된다)

 

 

버스 인터페이스(Bus Interface)

명령어와 데이터가 CPU로 어떻게 들어 왔을까? 바로 버스 인터페이스 때문이다. 서로 데이터를 주고 받기 위해서 어떤 매개체가 필요하다 그것이 바로 버스 인터페이스다.

'컴퓨터 기본' 카테고리의 다른 글

퀵소트 자바  (0) 2021.05.26
Thread 란?  (0) 2020.05.07
클래스 관계 HAS-A 상속(합성, 통합)  (0) 2019.11.08
class의 static이란?(실무에서 바로 통하는 자바)  (0) 2019.10.28
유니코드 vs 아스키코드  (0) 2019.06.14
전체코드
#include <iostream>
#include <cstring>
using namespace std;

class MyClass 
{
public:
	MyClass(const char _name[])
	{
		this->name = new char[strlen(_name) + 1];
		strcpy_s(this->name, strlen(_name) + 1, _name);
		cout << "기본 생성자 MyClass()" << this->name << endl;
	}

	MyClass(const MyClass& rhs)
	{
		this->name = new char[strlen(rhs.name) + 1];
		strcpy_s(this->name, strlen(rhs.name) +1, rhs.name);
		cout << rhs.name << "@@@@@@@@@@@복사 생성자 MyClass(const MyClass &rhs)@@@@@@@@@@" << endl;
	}

	//MyClass(MyClass&& rhs) : name(rhs.name)
	//{
	//	cout << rhs.name << "########## 이동 생성자(const MyClass&& rhs)##########" << endl;
	//  rhs.name = nullptr;
	//}

	operator string() { return this->name; }

	MyClass operator+(const MyClass& rhs)
	{
		cout << "operator+" << endl;
		MyClass temp(rhs.name);
		int thisNameLen = strlen(this->name);
		int rhsNameLen = strlen(rhs.name);
		strcat_s(temp.name, (thisNameLen + rhsNameLen + 1), this->name);
		return temp;
	}

	MyClass& operator=(const MyClass& rhs)
	{
		cout << "operator=" << endl;
		return *this;
	}

	void setName(const char _name[])
	{
		delete this->name;
		this->name = new char[strlen(_name) + 1];
		strcpy_s(this->name, strlen(_name) + 1, _name);
	}

	void printName()
	{
		cout << this->name << endl;
	}

private:
	char *name;
};


int main() 
{
	cout << "##########begin#########" << endl;
	MyClass a("aa"), b("bb"), c("cc");
	MyClass d = a + b + c;
	a.printName();
	cout << string(a) << endl;

	b.printName();
	cout << string(b) << endl;

	c.printName();
	cout << string(c) << endl;

	d.printName();
	cout << string(d) << endl;



	cout << "##########end#########" << endl;
	return 0;
}


// 출력값
##########begin#########
기본 생성자 MyClass()aa
기본 생성자 MyClass()bb
기본 생성자 MyClass()cc
operator+
기본 생성자 MyClass()bb
bbaa@@@@@@@@@@@복사 생성자 MyClass(const MyClass &rhs)@@@@@@@@@@
operator+
기본 생성자 MyClass()cc
ccbbaa@@@@@@@@@@@복사 생성자 MyClass(const MyClass &rhs)@@@@@@@@@@
aa
aa
bb
bb
cc
cc
ccbbaa
ccbbaa
##########end#########

MyClass라는 클래스를 만들고 인스턴스 a,b,c를 각각 정의했다.

이때는 당연히 기본생성자가 불린다.

파라미터 값으로 문자열을 받으니 _name[]으로 정의했다.

그런다음 name 포인터에 문자열을 담는 아주 간단한 기본 생성자이다.

 

문제는 MyClass d = a +b + c; 여기에 있다.

골때리게도 이 한줄이 이렇게 많은 생성자를 호출한다...

생성자를 호출한다는건 인스턴스가 생성된다는 뜻이고 여기에 따른 메모리, CPU Loss가 엄청나다.

 

여기서 주목해야할 부분은 바로 복사 생성자와 operator+ 더하기 연산자다. 

복사 생성자에서는 메모리 할당 문제 때문에 Deep Copy를 수행한다. (이전 글 참조)

2020/02/01 - [C++] - C++ 복사 생성자(참조형 파라미터)

 

C++ 복사 생성자(참조형 파라미터)

복사 생성자는 객체의 복사본을 생성할 때 호출되는 생성자이다. CMYData a CmyData b(a) 이처럼 원본 a의 복사본을 만들때 복사 생성자가 불린다. 문법은 클래스이름(const 클래스이름 &rhs) 처럼 사용한다. #inc..

leemoney93.tistory.com

operator + 를 살펴보자.

 

operator+
	MyClass operator+(const MyClass& rhs)
	{
		cout << "operator+" << endl;
		MyClass temp(rhs.name);
		int thisNameLen = strlen(this->name);
		int rhsNameLen = strlen(rhs.name);
		strcat_s(temp.name, (thisNameLen + rhsNameLen + 1), this->name);
		return temp;
	}
    
    a + b === a.operator+(b)

operator+에서는 할말이 아주 많은데 천천히 하나씩 해보면

1. operator+는 a+b를 할때 불리는 연산자이다.

2. a+b는 내부적으로 a.operator+(b)랑 같다

3. 그러므로 위의 코드 operator+의 rhs 값은 오른쪽 즉 b의 인스턴스의 참조이다.

4. operator+ 내부에서 temp 인스턴스를 생성하는데 b의 name값을 가지고 생성한다.

 ※ 기본 생성자 MyClass()bb 출력

5. a의 name값과 b의 name값을 합쳐서(strcat_s) MyClass instance temp를 return 한다.

 - (중요)이때 복사 생성자가 출력되는데 그 이유는 return temp를 할때 임시 객체를 생성하고 return 하기 때문이다.

MyClass(const MyClass& rhs)
{
  this->name = new char[strlen(rhs.name) + 1];
  strcpy_s(this->name, strlen(rhs.name) +1, rhs.name);
  cout << rhs.name << "@@@@@@@@@@@복사 생성자 MyClass(const MyClass &rhs)@@@@@@@@@@" << endl;
}
// 출력값
bbaa@@@@@@@@@@@복사 생성자 MyClass(const MyClass &rhs)@@@@@@@@@@

6. 위의 코드는 복사 생성자가 불릴땐데 rhs.name은 bbaa이다.

그러니깐 위의 temp instance를 기반으로 복사 생성이 이루어졌단뜻!

왜냐?? a + b를 하면 + c를 또 해야되는데(d = a + b + c) a + b의 결과 값을 가지는 임시 객체를 만들어야 하기 때문에 복사 생성이 필요하단 뜻이다. 근데 도대체 이동 생성이랑 무슨 관계인데?? 

위의 복사 생성은 Deep Copy를 하고있다. 아니 조만간 사라질놈이 왜 Deep 카피를 하냐 성능 떨어지게 그냥 포인터로 간단하게 끝내서 성능향상을 하면 되잖아! 이 논리로 나온게 바로 이동 생성이다.

MyClass(MyClass&& rhs) : name(rhs.name)
{
    cout << rhs.name << "########## 이동 생성자(const MyClass&& rhs)##########" << endl;
    rhs.name = nullptr;
}
    
// 출력값
bbaa########## 이동 생성자(const MyClass&& rhs)##########

전체코드의 주석을 풀자.

그럼 복사 생성자 대신 이동 생성자가 불린다.

이동 생성자의 rhs는 무엇일까? 바로 temp이다. 그러니깐 return temp를 할 때 temp instance를 기반으로 이동 생성자가 불렸다는 뜻. 당연하다 복사 생성자도 temp instance를 기반으로 했으니.

 

이동 생성자에서는 new로 메모리 할당받아서 Deep Copy이런거 안한다.

그냥 rhs.name(이때 rhs는 temp 임시 객체 r-value 참조)의 주소 값(포인터니깐)을 name에 할당 그러니깐 주소값만 name에 넣어주고 끝이다. 왜냐하면 조만간 사라질 임시 객체니깐! 그리고 그 값을 고스란히 return 하고 아름답게 전사한다. 이때 return 한 임시 객체 값은 + c 의 연산과정에서 또 쓰이게 된다!

 

이로써 Deep Copy(복사생성)에서 메모리 할당받고 어쩌고 저쩌고를 포인터 하나로 아주 성능 좋게 바꿨다.

 

 

'C++' 카테고리의 다른 글

C++ 멤버함수의 메모리 위치  (0) 2020.04.09
C++ 객체 생성  (0) 2020.04.02
C++ 대입 연산자  (0) 2020.02.02
C++ 깊은복사 얕은복사  (0) 2020.02.02
C++ 복사 생성자(참조형 파라미터)  (0) 2020.02.01
다중 정의를 이용한 대입 연산자

CMyData라는 Class의 인스턴스 a와 b가 있을때 a=b 이런것을 수행하면 어떻게 될까????? 당연히 에러난다

하지만 다중정의에서 적절한 값을 넣어준다면 인스턴스간의 = 연산자가 먹힐 수 있다.

 

#include <iostream>
using namespace std;

class CMYData
{

public:
	CMYData(int nParam)
	{
		m_pnData = new int;
		*m_pnData = nParam;
	};

	CMYData(CMYData& rhs)
	{
		m_pnData = new int;
		*m_pnData = *rhs.m_pnData;
	}

	CMYData& operator=(const CMYData& rhs)
	{
		*m_pnData = *rhs.m_pnData;

		return *this;
	}

	~CMYData()
	{
		delete m_pnData;
	}


	int GetData(void) { return *m_pnData; };

private:
	int *m_pnData = nullptr;
};


int main(void)
{
	CMYData a(10);
	CMYData b(20);
	CMYData c(30);

	cout << a.GetData() << endl;
	cout << b.GetData() << endl;
	cout << c.GetData() << endl;

	a = b = c;

	cout << a.GetData() << endl;
	cout << b.GetData() << endl;
	cout << c.GetData() << endl;

	return 0;
};

위의 코드에서 인스턴스 끼리 a=b=c 이러고 있다. 되는 이유는 바로 CMYData& operator=(const CMYData& rhs) 이것 때문이다.

 

operator=은 함수 이름이고 operator+나 operator- 같은 형태로 기본 연산자를 재정의할 수 있다.

여기선 m_pnData의 값을 바꿨다 그래서 a=b=c 코드 이후엔 모든 출력값이 모두 30으로 변경된 것을 알 수 있다.

 

'C++' 카테고리의 다른 글

C++ 객체 생성  (0) 2020.04.02
C++ 임시객체(이동 생성자) 중요!  (0) 2020.02.07
C++ 깊은복사 얕은복사  (0) 2020.02.02
C++ 복사 생성자(참조형 파라미터)  (0) 2020.02.01
C++ this 포인터  (0) 2020.02.01
사전적 의미

깊은 복사는 실제로 두 개의 값(인스턴스가) 생성 되는 것이고, 얕은 복사는 원본은 하난데 포인터가 두개인 것이다.

 

얕은복사로 인한 에러 발생
#include <iostream>
using namespace std;

class CMYData
{
public:
	CMYData(int nParam)
	{
		m_pnData = new int;
		*m_pnData = nParam;
	};

	~CMYData()
	{
		delete m_pnData;
	};


	int GetData(void) { return *m_pnData; };

private:
	int *m_pnData = nullptr;
};


int main(void)
{
	CMYData a(10);
	CMYData b(a);
	cout << a.GetData() << endl;
	cout << b.GetData() << endl;

	return 0;
}

위의 코드를 실행하면 인스턴스 b의 소멸자를 Call 할 때 에러가 발생한다.

왜냐?? 진짜 중요한 개념인데 b의 Default 복사 생성자는 포인터를 제대로 처리하지 못하기 때문이다.

좀 더 자세히 말하면 인스턴스 b도 생성 될 때 새롭게 동적 할당 받아서 거기다가 값을 집어 넣야아하는데 Defalut 복사 생성자는 인스턴스 a의 m_pnData 값 즉 a에서 동적 할당 한 값을 그대로 b의 m_pnData에 집어 넣었기 때문이다. 그러니깐 인스턴스 a가 소멸될때 delete를 했는데 b가 소멸될 때 없는 메모리를 delete 하려 하니 에러가 발생하는것! 

 

깊은복사로 에러 탈출!
	CMYData(CMYData& rhs)
	{
		m_pnData = new int;
		*m_pnData = *rhs.m_pnData;
	}

위와 같은 복사 생성자를 넣어주자. 그럼 인스턴스 b도 생성될때 int 형 만큼의 Heap 메모리를 할당 받아서 그 메모리에 값을 쓴다!

'C++' 카테고리의 다른 글

C++ 임시객체(이동 생성자) 중요!  (0) 2020.02.07
C++ 대입 연산자  (0) 2020.02.02
C++ 복사 생성자(참조형 파라미터)  (0) 2020.02.01
C++ this 포인터  (0) 2020.02.01
C에서 C++ 객체지향의 변환 과정  (0) 2020.01.28
복사 생성자는 객체의 복사본을 생성할 때 호출되는 생성자이다.

CMYData a

CmyData b(a)

 

이처럼 원본 a의 복사본을 만들때 복사 생성자가 불린다.

문법은 클래스이름(const 클래스이름 &rhs) 처럼 사용한다.

 

#include <iostream>
using namespace std;

class CMYData
{
public:
	CMYData() { cout << "기본 생성자" << endl; };
	CMYData(const CMYData &rhs) 
	{
		this->m_nData = rhs.m_nData;
		cout << "복사 생성자" << endl;
	};

	int GetData(void) { return m_nData; };
	void SetData(int nParam) { m_nData = nParam; };

private:
	int m_nData;
};

int main(void)
{
	CMYData a;
	a.SetData(10);

	CMYData b(a);
	cout << b.GetData() << endl;
	return 0;
}

// 출력값
// 기본 생성자
// 복사 생성자
// 10

이런 식으로 CMYData b(a)와 같은 상황일 때 복사 생성자가 불린다. 여기서 rhs는 원본 즉 a 인스턴스의 참조 변수이다.

이것만 봐서는 도대체 복사 생성자가 왜 중요한지 모르겠다. 하지만 매개변수로 사용되는 복사 생성자를 보면 성능에 대해서 아주 중요한 이야기가 나온다. 결론은 가능하면 무조건 참조형으로 받자! 왜냐? 인스턴스가 하나 더 생성 되니깐

참조형으로 받겠다는 말은 주소로 넘기자 이말이다(call by reference)

 

매개변수로 사용되는 복사 생성자
#include <iostream>
using namespace std;

class CMYData
{
public:
	CMYData(int nParam)
		:m_nData(nParam)
	{
		cout << "기본 생성자" << endl; 
	};

	CMYData(const CMYData &rhs) 
		:m_nData(rhs.m_nData)
	{
		cout << "복사 생성자" << endl;
	};

	int GetData(void) { return m_nData; };
	void SetData(int nParam) { m_nData = nParam; };

private:
	int m_nData;
};

void TestFunc(CMYData param)
{
	cout << "TestFunc" << endl;
	param.SetData(20);
}

int main(void)
{
	CMYData a(10);
	TestFunc(a);
	cout << a.GetData() << endl;

	return 0;
}

//출력값
//기본 생성자
//복사 생성자
// TestFunc
// 10

다 집어치우고 main함수에서 TestFunc(a)를 호출하면 복사 생성자가 호출된다 왜냐하면 TestFunc의 매개변수는 CMYData param이기 때문이다. 그러니깐 param은 CMYData의 새로운 인스턴스다. 인스턴스를 하나 더 만들었다.

골때린다. 그리고 그 새로운 인스턴스에 20값을 집어 넣어놓고는 인스턴스가 삭제됐다(스택 프레임 종료). 그러니 a는 여전히 10일 수 밖에.. 아무것도 못하고 성능 낭비 메모리 낭비만 하고 사라지는 거지같은 함수 TestFunc다. 이것을 아주 우아하게 바꾸려면 앞에 & 참조만 붙여주면 된다.

바로 void TestFunc(CMYData &param)이렇게! 이렇게 해야 call by reference로 주소만 넘긴다! 객체를 생성하지도 않고 성능도 아주 좋다.

'C++' 카테고리의 다른 글

C++ 대입 연산자  (0) 2020.02.02
C++ 깊은복사 얕은복사  (0) 2020.02.02
C++ this 포인터  (0) 2020.02.01
C에서 C++ 객체지향의 변환 과정  (0) 2020.01.28
C++ 참조자 형식(reference)  (0) 2020.01.27
this 포인터

this->변수, 파이썬에서는 self.변수 등등 으로 this라는 놈은 OOP에서 상당히 자주 등장하는 개념이고 중요한 개념이다.

C의 포인터와 C++의 객체지향 개념을 이해하면 this라는 놈을 정확하게 알 수 있다. 상당히 귀여운 놈이다.

 

this 포인터는 클래스의 실제 인스턴스에 대한 주소를 가르키는 포인터다.

 

좀 더 풀어서 이야기하면 this는 포인터 변수인데, 실제 인스턴스의 주소를 값으로 가지는 변수이다.

 

#include <iostream>
using namespace std;

typedef struct USERDATA
{
	int nAge;
	char szName[32];
} USERDATA;


class CMYData
{
public:
	CMYData(int nParam) : m_nData(nParam) {};
	void PrintData()
	{
		// 인스턴스 a가 만들어질때는 this와 &a는 같은주소
		// 인스턴스 b가 만들어질때는 this와 &b는 같은주소
		cout << this->m_nData << endl;
		cout << this->CMYData::m_nData << endl;
	}

private:
	int m_nData;
};

int main(void)
{
	CMYData a(5), b(10);
	a.PrintData();
	b.PrintData();
	return 0;
}

- CMYData 클래스 안의 PrintData 메소드는 this를 통해서 m_Data를 접근하고 있다. a.PrintData()를 Call 할 때 this는 &a와 같은 값을 가지고, b.PrintData()를 Call 할 때 this는 &b와 같은 값을 가진다. a.PrintData()는 사실 a.PrintData(&a)와 같다. 파라미터로 &a를 안넘겨도 되는 이유는 C++가 알아서 처리 해주기 때문이다(히든 파라미터라고 부름)

 

this의 실체
class CMYData
{
public:
	CMYData(int nParam) : m_nData(nParam) {};
	void PrintData(CMYData *pData)
	{
		CMYData* myThis = pData;
		// myThis를 통해서 변수에 접근하고있다.
		cout << myThis->m_nData << endl;
		cout << myThis->CMYData::m_nData << endl;
	}

private:
	int m_nData;
};

int main(void)
{
	CMYData a(5), b(10);
	a.PrintData(&a);
	b.PrintData(&b);
	return 0;
}

이번에는 C++가 알아서 처리해주는 히든파라미터 말고 진짜로 주소값을 넘겨봤다. 주소 값이니깐 당연히 포인터를 써주고 그 포인터가 가르키는 대상은 CMYData이다.

'C++' 카테고리의 다른 글

C++ 깊은복사 얕은복사  (0) 2020.02.02
C++ 복사 생성자(참조형 파라미터)  (0) 2020.02.01
C에서 C++ 객체지향의 변환 과정  (0) 2020.01.28
C++ 참조자 형식(reference)  (0) 2020.01.27
C++ new 메모리 동적할당  (0) 2020.01.27
C언어(태초)
#include <iostream>

typedef struct USERDATA
{
	int nAge;
	char szName[32];
} USERDATA;

int main(void)
{
	USERDATA user = { 28, "승우" };
	printf("%d, %s\n", user.nAge, user.szName);
	return 0;
}

간단한 C언어이다. 이 USERDATA라는 놈을 출력 하려면 사용자가 USERDATA 구조체의 구성을 다 알아야 한다. (nAge의 타입은 int니깐 %d로 찍고 등등)

 

만약 USERDATA 구조체를 만든 제작자가 출력해주는 코드를 같이 짜준다면??

#include <iostream>

typedef struct USERDATA
{
	int nAge;
	char szName[32];
} USERDATA;

void PrintData(USERDATA* pUser)
{
	printf("%d, %s\n", pUser->nAge, pUser->szName);
}

int main(void)
{
	USERDATA user = { 28, "승우" };
	PrintData(&user);
	return 0;
}

사용자는 그저 PrintData를 호출하기만 하면 된다. USERDATA의 멤버의 구성을 일일히 다 알 필요가 없다는 뜻!

이런 PrintData를 인터페이스 함수라고 부른다.(내부는 모르겠고 인터페이스를 통해서 알아서 좀 해줘~!)

 

근데 좀 허전하다 USERDATA 구조체와 PrintData가 무슨 관계가 있는지 어떻게 아냐? 좀 묶을 필요가 있다. 사용자가 헷갈리지 않도록.

 

구조체안에 함수도 한번 넣어봐라.

#include <iostream>

typedef struct USERDATA
{
	int nAge;
	char szName[32];
	void(*MyPrint)(struct USERDATA*);
} USERDATA;

void PrintData(USERDATA* pUser)
{
	printf("%d, %s\n", pUser->nAge, pUser->szName);
}

int main(void)
{
	USERDATA user = { 28, "seungwoo", PrintData};
	user.MyPrint(&user);
	return 0;
}

구조체 USERDATA의 주소값을 파라미터로 가지는 MyPrint 함수를 구조체 안에 넣었다. 그리고 PrintData로 초기화했다.

진짜 구조체안에 함수를 넣으려고 애썼다. 근데 한가지 아쉬운점은 자기자신의 주소를 한번 더 파라미터로 넘긴다는점.

야 니꺼 니가 접근하는데 도대체 니 주소를 왜...?? 안되겠다 Class 만들자.

 

C++ Class  탄생
class USERDATA
{
public:
	int nAge;
	char szName[32];

	void MyPrint(void)
	{
		std::cout << this->nAge << " " << this->szName << std::endl;
	}
};


int main(void)
{
	USERDATA user = { 28, "seungwoo"};
	user.MyPrint();
	return 0;
}

이런식으로 만들면 정말 이쁘다 이뻐.. c++에서 MyPrint 메소드를 호출할 때 사실은 &user가 파라미터로 넘어간다. 이것을 히든 파라미터라고 부른다.

'C++' 카테고리의 다른 글

C++ 깊은복사 얕은복사  (0) 2020.02.02
C++ 복사 생성자(참조형 파라미터)  (0) 2020.02.01
C++ this 포인터  (0) 2020.02.01
C++ 참조자 형식(reference)  (0) 2020.01.27
C++ new 메모리 동적할당  (0) 2020.01.27

+ Recent posts