const와 namespace에 관한 사소한 궁금점 그리고 한가지 더

프로그래밍 일반에 관한 포럼입니다.

Moderator: 류광

Locked
fireheart
Posts: 98
Joined: 2004-02-12 19:50
Location: 토성연합

const와 namespace에 관한 사소한 궁금점 그리고 한가지 더

Post by fireheart »

안녕하세요. namespace와 const. 잘 안쓰다가 최근에 몇몇 책을 보고 쓰게 되었는데요, 궁금한 점이 있어서 질문올립니다.

사소한 질문들이라 한꺼번에 묶어서 합니다. =0=


첫번째 const에 관한겁니다.

다음과 같은 코드를 짜봤습니다.

Code: Select all

class T
{
public:
	int m_nData;
public:
	T() { } 
	T(int data) : m_nData(data) { } 

	T operator + (const T& t)
	{
		return m_nData + t.m_nData;
	}
	T operator - (const T& t)
	{
		return m_nData - t.m_nData;
	}

	void operator += (const T& t)
	{
		m_nData += t.m_nData;
	}

	void operator -= (const T& t)
	{
		m_nData -= t.m_nData;
	}

    operator int()
	{
        return m_nData;
	}
	
};

int main(int argc, char* argv)
{
	const int A = 10;
	const int B = 20;

	//당연히 된다.
	int C = B - A;		
	int D = B + A;
	printf("%d %d\n",C,D);

	const T dataA(10);
	const T dataB(20);

	/*
	//왜 허용하지 않을까?
	T dataC = dataB - dataA; 
	T dataD = dataB + dataA;
	*/

	//다른 방법 
	T dataC(dataB);
	dataC -= dataA;
	
	T dataD(dataB);
	dataD += dataA;
	printf("%d %d\n",(int)dataC, (int)dataD);

	return 0;
}
주석에 적은 것 처럼, const int A, const int B, int C = B - A는 허용하는데
클래스로 만들어서 const를 붙이면 허용하지 않네요.

그 이유가 뭔가요? 주석에 적힌 다른 방법은 깔끔하지가 않아서 마음에 들지 않습니다. 애초에 왜 허용하지 않는가도 궁금하구요. 다른 방법이 있는건가요?


두번째 namespace 입니다.
Test.h

Code: Select all

#pragma once

namespace HWI
{

class Test
{
public:
    int m_nData;
public:
	Test(void);
	Test(int data);
	~Test(void);
};

Test operator * (int scalar, const Test& t);

};

Test.cpp

Code: Select all

#include ".\test.h"
using namespace HWI;

Test::Test(void)
{
}

Test::Test(int data) : m_nData(data) 
{ 
} 

Test::~Test(void)
{
}


Test operator * (int scalar, const Test& t)
{
	return Test(t.m_nData * scalar);
}
Main.cpp

Code: Select all

#include <stdio.h>
#include "Test.h"

using namespace HWI;

int main(int argc, char** argv)
{
	Test tA(2);
    Test tB = 3 * tA;
	printf("%d\n",tB.m_nData);
	return 0;
}

여기서 빌드를 하면
namespace error LNK2019: "class HWI::Test __cdecl HWI::operator*(int,class HWI::Test const &)" (??DHWI@@YA?AVTest@0@HABV10@@Z) 외부 기호(_main 함수에서 참조)를 확인하지 못했습니다.
라고 나옵니다.

그래서 operator 함수 정의를

Code: Select all

Test HWI::operator * (int scalar, const Test& t)
{
	return Test(t.m_nData * scalar);
}
와 같이 'HWI::'를 붙여 범위를 명확히 해주면 됩니다.


분명 앞에 'using namespace HWI;'를 썼는데 왜 이렇게 해야하는건가요?

const와 namespace 내가 잘못사용하고 있는건가? 라는 생각도 듭니다.



세번째로 지금 MATH 라이브러리 작업 중인데
Vector, Matrix, Quaternion은 Math.lib로 만들고 그걸 참조하는 Geometry 라이브러리를 만들려고 합니다.

이것은 Ray, AABBo, OBB, Plane, Poly, Sphere, Cylinder, Torus를 수학적으로 정의하는 라이브러리 입니다.

고민되는건 이것을 MATH라이브러리에 왕창 집어 넣는게 좋을지 아니면 Geometry.lib가 Math.lib를 포함해서 만드는게 좋을지 고민되네요.

지금 생각으로는 Vector, Matrix, Quaternion 만 필요할 경우 Math.lib만 가지고 가게 Geometry 라이브러리를 따로 만들 생각인데, 다른 분들을 어떻게 생각하시는지?


아무거나 답변 부탁드립니다.(__)
한걸음씩 천천히 나아가자!
류광
Posts: 3805
Joined: 2001-07-25 09:00
Location: GPGstudy
Contact:

Re: const와 namespace에 관한 사소한 궁금점 그리고 한가지 더

Post by 류광 »

1. const 질문...

멤버 함수를 호출할 때 숨겨진 this가 전달되는 것은 알고 계시죠?
T::func()일 때 this는 T*입니다. T::func() const일 때 this는 const T*이구요.

T dataC = dataB - dataA; 의 경우 dataB가 const이기 때문에 operator+()의 this로 const &dataB가 전달됩니다. 즉 const T*가 전달됩니다. 그런데 지금의 operator-()가 기대하는 this는 const가 없는 T*입니다. 그래서 다음 상황과 본질적으로 동일한 일이 일어납니다...

Code: Select all

void foo(T*) {}
...

const T t;
foo(&t); //  오류 - const T*를 T*로 변환할 수 없음.
해결책은 연산자를 const 멤버로 함수로 만드는 것입니다. 이러면 this가 const T*가 되므로 오류가 생기지 않습니다.

void operator - (const T& t) const

2. 이름공간...

잠깐 착각을 하신 것 같은데 그냥... 클래스 멤버 함수를 구현할 때 클래스이름::를 붙여야 하는 것과 동일한 사항입니다... 그 부분은 using namespace와는 상관이 없습니다.

3번은 나중에~(또는 다른 분이!)
fireheart
Posts: 98
Joined: 2004-02-12 19:50
Location: 토성연합

Post by fireheart »

답변 감사합니다.
using namespace 부분은 잘못알고 있었네요.

멤버 함수 끝에 const 붙여주는건 그냥 멤버 데이터를 변경해주지 않는걸로만 알고 있었는데, 그런 뜻이~~

답변 감사합니다. (__)
한걸음씩 천천히 나아가자!
비회원

Re: const와 namespace에 관한 사소한 궁금점 그리고 한가지 더

Post by 비회원 »

Code: Select all

class T
{
public:
	int m_nData;
public:
	T() { } 
	T(int data) : m_nData(data) { } 

	T operator + (const T& t) const
	{
		return m_nData + t.m_nData;
	}
	T operator - (const T& t) const
	{
		return m_nData - t.m_nData;
	}

	void operator += (const T& t)
	{
		m_nData += t.m_nData;
	}

	void operator -= (const T& t)
	{
		m_nData -= t.m_nData;
	}

    operator int()
	{
        return m_nData;
	}
	
};

int main(int argc, char* argv)
{
	const int A = 10;
	const int B = 20;

	//당연히 된다.
	int C = B - A;		
	int D = B + A;
	printf("%d %d\n",C,D);

	const T dataA(10);
	const T dataB(20);

	
	//되지 않을까?
	T dataC = dataB - dataA; 
	T dataD = dataB + dataA;
	

	//다른 방법 
	T dataC(dataB);
	dataC -= dataA;
	
	T dataD(dataB);
	dataD += dataA;
	printf("%d %d\n",(int)dataC, (int)dataD);

	return 0;
}
Locked