C++ 함수 포인터에 관해 질문 있습니다.

greathero의 이미지

책을 보다가 std::tr1::function으로 함수 포인터를 쓰는 예제를 봤는데요.
이해가 안가는게 있어서 질문합니다.

class GameCharacter;
int defaultHealth(const GameCharater& rhs);
 
class GameCharacter { 
public:
	typedef std::tr1::function<int (const GameCharacter& rhs)> GetHealthFunc; // 함수 포인터 타입선언
	explicit GameCharacter(GetHealthFunc hfc = defaultHealth)
		:healthFunc(hfc) { } 
 
	int healthValue() const { return healthFunc(*this); } 
private:
	GetHealthFunc healthFunc;
};

생성자에서 게임 캐릭터의 HP를 계산하는 함수 포인터를 넘기는건 알겠는데요.
(안 넘기면 defaultHealth로 일반적인 방법으로 게임 캐릭터의 HP를 계산하겠다는 것일테고요.)
그런데, healthValue 함수에서 왜 return healthFunc(*this);를 하나요?
이게 GameCharacter에 매핑된 HP 계산함수를 쓴다는 목적에서 작성된 함수일텐데...
return healthFunc(defaulthHealth); <- 이런식으로 써야되는거 아닌가요?

return healthFunc(*this); 이 문장이 문법적으로 이해가 가질 않습니다ㅠ 도와주세요...

oosap의 이미지

*this 는 객체가 자기자신을 값으로 어떤 함수에 전달할 때 사용하는 것 아닌가요?

typedef std::tr1::function<int (const GameCharacter& rhs)> GetHealthFunc

를 보았을 때 GetHealthFunc 은
std::tr1::function<int (const GameCharacter& rhs)> 

의 다른 이름이고
std::tr1::function<int (const GameCharacter& rhs)>
가 어떻게 인스턴스화 되는지 알아야겠네요..

아마 그것은 int (const GameCharacter& rhs) 형식의 함수 포인터인 듯 하고 그렇다면 그 함수는 인자로 const GameCharacter& rhs 를 받고요, *this 를 받을 수 있는 형식인 것 같습니다.

함수 포인터 타입선언의 형식이 좀 복잡하네요...

Thanks for being one of those who care for people and mankind.
I'd like to be one of those as well.

chadr의 이미지

단순하게 생각하시면 됩니다.

explicit GameCharacter(GetHealthFunc hfc = defaultHealth)
:healthFunc(hfc) { }

여기 생성자에서 보듯이 생성자의 인자로 넘어오는 인자의 기본 값이 defaultHealth입니다.
인자로 안넘겨주면 기본 값을 쓰고 넘어오면 넘어온 것이 hfc로 넘어올겁니다. 뭐 어쨌든....
넘어오건 안넘어오건간에 일단 hfc는 뭔가 항상 값을 가지고 있습니다.

그걸 :healthFunc(hfc) 통해서 멤버 변수의 생성자를 호출하여 초기화 했습니다.

그럼 healthFunc이라는 변수의 타입을 봅시다.

GetHealthFunc healthFunc

이렇게 선언 되어있네요. healthFunc라는 것은 GetHealthFunc 타입을 가집니다.

그러면 GetHealthFunc 타입이 뭔지 봐야겠죠.

typedef std::tr1::function GetHealthFunc;

이렇게 해서 타입은 선언했습니다. 복잡하지만 그냥 간단하게 하면 int (const GameCharacter& rhs) 타입입니다. 즉 함수 포인터 타입이지요.

따라서 healthFunc는 함수 포인터입니다. 함수 포인터를 이용해서 함수 호출을 하려면 그냥 일반 함수 호출하듯이 healthFunc(인자); 이렇게 하면 됩니다.

그런데 저 함수 포인터가 인자로 취하는게 뭐죠? 인자로 받는 것이 GameCharacter& rhs이지요.
참조자로 받기 때문에 포인터가 아닌 값을 넘겨야합니다.

그런데 this는 포인터입니다. 자기 자신을 가르키는 포인터.

포인터가 가리키는 것의 값을 가져오려면 앞에 * 연산자를 붙여야합니다.

그래서 *this는 자기 자신값입니다.

그걸 GameCharacter& rhs으로 넘겨준 것입니다.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.