C++ operator ->()에 대해서...

htna의 이미지

struct CC {
	int value;
};

struct CB {
	CC cc;
	CC* operator->() {
		return &cc;
	}
};

struct CA {
	CB cb;
	CB& operator->() {
		return cb;
	}
};

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	CA ca;
	ca->value = 2;
	return 0;
}

이러한 코드가 있습니다.
컴파일이 잘 되고, 잘 돌아갑니다.
이게 왜 되는거죠 ?
ca->value = 2;
에서 컴파일시에 에러가 나야 하는거 아닌가요 ?
혹시 이유 아시는 분 있나요 ???
htna의 이미지

위의 문제 잘은 안돌아가는군요.
컴파일은 되는데, 결과가 예상한대로가 아니네요..
근데...

struct CC {
	int value;
};

struct CB {
	CC cc;
	int value;
	CC* operator->() {
		return &cc;
	}
};

struct CA {
	CB cb;
	CB& operator->() {
		return cb;
	}
};

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	CA ca;
	ca->value = 2;
	return 0;
}

이것도 되네요...
혹시 원인 아시는 분이나. 어떻게 해야지 제대로 동작하는지 아시는 분 있나요 ??

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

익명 사용자의 이미지

의도하시는 바를 잘 모르겠지만, 사용자 정의형에 대한 operator-> 는

컴파일러가 원시 포인터 형을 찾아낼 때 까지 operator-> 를 연속적으로

적용시킨다고 합니다.


   ca->value = 2;


    ((ca.operator->()).operator->())->value = 2;

같습니다.

두번째 코드에서 CB::value 에 2를 넣고 싶으시면

    ca.operator->().value = 2;

를 하시면 됩니다.

htna의 이미지

감사합니다.
근데 어떻게 돌아가는지 원문을 보고 이해하고 싶네요..
원문을 어디서 구할 수 있는지 알려주시면 감사하겠습니다.
생각과 달리 "->"는 적용되는 방식이 좀 생각을 해서 작성해야 할 듯 하네요..

현재 stl의 list, vector, set, map, multiset, multimap 을 repackaging하는 작업을 하고 있습니다.
그중에서 처리가 어려운것이 map, multimap이군요..
value_type으로 std::pair<>를 들고 있기에..
iter->first, iter->second 형식으로 key와 value를 접근하기 때문에...
iter->second를 처리해야 하는 부분을 처리하기가 어렵군요...
그걸 처리하려 하다보니.. -> 를 다중처리로 접근하도록 하니 해결되는 듯 해서..
의아해서 질문을 올린 겁니다.
알고 넘어가야 할 듯 해서요...

혹시 이런질문을 올렸을때 자세한 답변이나 설명을 들을 수 있는 사이트나, 머 그런데 있나요 ?
하는일이 C++ template을 복잡하게 다뤄야 하는 경우가 종종 있다보니. 가끔 어려운부분에 막히는 곳이 있습니다.
여기가 그나마 실력자들이 좀 있는듯 하긴 합니다만. 다른곳도 참조할 만한 곳이 있나 해서요..

"operator ->()"를 어디를 참조해야 할 지 알려주시면 정말 감사하겠습니다.
그럼 좋은하루 되시기 바랍니다.

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

happyjun의 이미지

제가 본 operator ->() 의 예는 Andrei Alexandrescu 의 Modern C++ Design 에서 smart pointer를 위한 lock proxy를 만들 때 봤습니다.

윗 분이 설명하신 것처럼 원시 포인터형이 나올 때 까지 operator->()를 호출하기 때문에 중간에 proxy를 넣을 수도 있습니다.

class Widget
{
   ...
   void Lock();
   void Unlock();
   void DoSomthing();
};

template <class T>
class LockingProxy
{
public:
   LockingProxy(T* pObj) : pointee_ (pObj)
   { pointee_->Lock(); }
   ~LockingProxy()
   { pointee_->Unlock(); }
   T* operator->() const
   { return pointee_; }
private:
   LockingProxy& operator=(const LockingProxy&);
   T* pointee_;
};

template <class T>
class SmartPtr
{
   ...
   LockingProxy<T> operator->() const
   { return LockingProxy<T>(pointee_); }
private:
   T* pointee_;
};


SmartPtr<Widget> sp = ...;
sp->DoSomething();

----------------------------------------
http://moim.at
http://mkhq.co.kr

happyjun의 이미지

그리고 C++에 대한 심도 있는 질문은 http://groups-beta.google.com/group/comp.lang.c++.moderated

에서 하시면 여러 구루가 답해 주실 겁니다. :)

ps. 책에 대한 질문을 하면 저자들도 답하더군요. :)

----------------------------------------
http://moim.at
http://mkhq.co.kr

htna의 이미지

구글 뉴스그룹이 있었군요..
좋은정보 감사드립니다.
음...
그나저나. 웹으로 구할 수 있는 문서나 그러한 참고자료 없을까요 ?
그걸 보고 싶어서.. ^^

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

doldori의 이미지

operator->()의 문법은 사실 별 거 없습니다.

Quote:
13.5.6 Class Member Access

operator-> shall be a non-static member function taking no parameters.
It implements class member access using ->
postfix-expression -> id-expression
An expression x->m is interpreted as (x.operator->())->m for a class
object x of type T if T::operator->() exists and if the operator is selected
as the best match function by the overload resolution mechanism (13.3).


TC++PL에도 나와 있는데 문법보다는 의미론에 관한 내용이 더 많군요.
htna의 이미지

아. 유독 찾기 어려운게 그렇군요..
"그냥 이렇다더라.." 하고 들은 지식은 생각보다 깊이 새겨지지 않고, 오래가지 않는 경향이 있는것 같습니다.
아무래도 확실히 문서를 보고 인식한게 무의식적으로도 오래 남는것 같아서요..
그래서 문서를 보려고 한 것입니다만..
역시나 문서를 구하기는 어렵군요..
답변해주신분들 감사드립니다.
모두들 좋은하루 되시길...

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

익명 사용자의 이미지

저도 번역판 modern c++ design 의 스마트 포인터 부분을 보고

드린 답변이었습니다.

modern c++ design 의 스마트 포인터 부분 원문이라면

http://www.informit.com/articles/article.asp?p=31529&seqNum=3

에서 보실 수 있으실 겁니다. (원문을 거의 그대로 옮긴지라 그다지

도움이 되지는 않을 겁니다.)

htna의 이미지

네 감사합니다.
잘 참고하겠습니다.

WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.