Program Language/C & C++

[C++] 포인터와 참조

야곰야곰+책벌레 2021. 12. 29. 15:52
728x90
반응형

포인터와 참조는 서로 다른 위치의 객체를 참조하는 두 가지 메커니즘이다. 이 유사성을 그래픽으로 표시할 수 있다.

각각의 강점과 약점이 있다. 참조할 객체를 변경해야 하는 경우 포인터를 사용한다. =, +=, ++ 및 -- 를 사용하여 포인터 변수의 값을 변경할 수 있다.

void fp(char∗ p)
{
	while (∗p)
		cout << ++∗p;
}
void fr(char& r)
{
	while (r)
		cout << ++r; // oops: increments the char referred to, not the reference
			     // near-infinite loop!
}
void fr2(char& r)
{
	char∗ p = &r; // get a pointer to the object referred to
	while (∗p)
		cout << ++∗p;
}

반대로 이름이 항상 동일한 객체를 참조하도록 하려면 참조를 사용하자.

template<class T> class Proxy { // Proxy refers to the object with which it is initialized
	T& m;
public:
	Proxy(T& mm) :m{mm} {}
	// ...
};

template<class T> class Handle { // Handle refers to its current object
	T∗ m;
public:
	Proxy(T∗ mm) :m{mm} {}
	void rebind(T∗ mm) { m = mm; }
	// ...
};

객체를 참조하는 항목에 대해 사용자 정의(오버로드) 연산자를 사용하려면 참조를 사용하자.

Matrix operator+(const Matrix&, const Matrix&); // OK
Matrix operator−(const Matrix∗, const Matrix∗); // error : no user-defined type argument
Matrix y, z;
// ...
Matrix x = y+z; // OK
Matrix x2 = &y−&z; // error and ugly

포인터와 같은 내장 유형 쌍에 대한 연산자를 (재)정의할 수 없다.

객체를 참조하는 컬렉션을 원하면 포인터를 사용해야 한다.

int x, y;
string& a1[] = {x, y}; // error : array of references
string∗ a2[] = {&x, &y}; // OK
vector<string&> s1 = {x , y}; // error : vector of references
vector<string∗> s2 = {&x, &y}; // O

C++가 프로그래머에게 선택의 여지를 남기지 않는 경우를 제외하면 나머지는 사용자의 미학의 영역이다. 이상적으로는 오류 가능성을 최소화하고 특히 코드의 가독성을 최대화하도록 선택해야 한다.

'no value'라는 개념이 필요한 경우 포인터는 nullptr을 제공한다. 이에 상응하는 'null 참조'가 없으므로 'no value'가 필요한 경우 포인터를 사용하는 것이 가장 적절하다.

void fp(X∗ p)
{
	if (p == nullptr) {
		// no value
	}
	else {
		// use *p
	}
}

void fr(X& r) // common style
{
	// assume that r is valid and use it
}

정말로 원한다면 특정 유형에 대한 'null 참조'를 구성하고 확인할 수 있다.

void fr2(X& r)
{
	if (&r == &nullX) { // or maybe r==nullX
		// no value
	}
	else {
		// use r
	}
}

분명히 nullX를 적절하게 정의해야 한다. 스타일이 관용적이지 않고 추천하지 않는다. 프로그래머는 참조가 유효하다고 가정할 수 있다. 유효하지 않은 참조를 생성하는 것이 가능하지만 그렇게 하기 위해 노력해야 한다.

char∗ ident(char ∗ p) { return p; }
char& r {∗ident(nullptr)}; // invalid cod

이 코드는 유효한 C++ 코드가 아니다. 

728x90
반응형

'Program Language > C & C++' 카테고리의 다른 글

[C++] 구조체 layout  (0) 2022.01.03
[C++] 구조체 (structure)  (0) 2021.12.29
[C++] 참조에 대한 참조  (0) 2021.12.29
[C++] rvalue 참조  (0) 2021.12.29
[C++] lvalue 참조  (0) 2021.12.29