Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>What will follow is not technically speaking a straight answer to your question as it will still make use of the "friend" functionality but it does not require modification of the tested entity itself and I think it addesses the concern of breaking the encapsulation mentioned in some of the other answers; it does though require writing some boilerplate code.</p> <p>The idea behind it is not mine and the implementation is <a href="http://bloglitb.blogspot.be/2011/12/access-to-private-members-safer.html" rel="nofollow">entirely based on a trick presented and explained by litb on his blog</a>(coupled with this <a href="http://www.gotw.ca/publications/mill02.htm" rel="nofollow">Sutter's gotw</a> for just a little bit more context, at least for me) - in short CRTP, friends, ADL and pointers to members (I must confess that to my dismay the ADL part I still don't get it entirely, but I'm relentesly working in figuring it out 100%).</p> <p>I tested it with gcc 4.6, clang 3.1 and VS2010 compilers and it works perfectly.</p> <pre><code>/* test_tag.h */ #ifndef TEST_TAG_H_INCLUDED_ #define TEST_TAG_H_INCLUDED_ template &lt;typename Tag, typename Tag::type M&gt; struct Rob { friend typename Tag::type get(Tag) { return M; } }; template &lt;typename Tag, typename Member&gt; struct TagBase { typedef Member type; friend type get(Tag); }; #endif /* TEST_TAG_H_INCLUDED_ */ /* tested_class.h */ #ifndef TESTED_CLASS_H_INCLUDED_ #define TESTED_CLASS_H_INCLUDED_ #include &lt;string&gt; struct tested_class { tested_class(int i, const char* descr) : i_(i), descr_(descr) { } private: int i_; std::string descr_; }; /* with or without the macros or even in a different file */ # ifdef TESTING_ENABLED # include "test_tag.h" struct tested_class_i : TagBase&lt;tested_class_i, int tested_class::*&gt; { }; struct tested_class_descr : TagBase&lt;tested_class_descr, const std::string tested_class::*&gt; { }; template struct Rob&lt;tested_class_i, &amp;tested_class::i_&gt;; template struct Rob&lt;tested_class_descr, &amp;tested_class::descr_&gt;; # endif #endif /* TESTED_CLASS_H_INCLUDED_ */ /* test_access.cpp */ #include "tested_class.h" #include &lt;cstdlib&gt; #include &lt;iostream&gt; #include &lt;sstream&gt; #define STRINGIZE0(text) #text #define STRINGIZE(text) STRINGIZE0(text) int assert_handler(const char* expr, const char* theFile, int theLine) { std::stringstream message; message &lt;&lt; "Assertion " &lt;&lt; expr &lt;&lt; " failed in " &lt;&lt; theFile &lt;&lt; " at line " &lt;&lt; theLine; message &lt;&lt; "." &lt;&lt; std::endl; std::cerr &lt;&lt; message.str(); return 1; } #define ASSERT_HALT() exit(__LINE__) #define ASSERT_EQUALS(lhs, rhs) ((void)(!((lhs) == (rhs)) &amp;&amp; assert_handler(STRINGIZE((lhs == rhs)), __FILE__, __LINE__) &amp;&amp; (ASSERT_HALT(), 1))) int main() { tested_class foo(35, "Some foo!"); // the bind pointer to member by object reference could // be further wrapped in some "nice" macros std::cout &lt;&lt; " Class guts: " &lt;&lt; foo.*get(tested_class_i()) &lt;&lt; " - " &lt;&lt; foo.*get(tested_class_descr()) &lt;&lt; std::endl; ASSERT_EQUALS(35, foo.*get(tested_class_i())); ASSERT_EQUALS("Some foo!", foo.*get(tested_class_descr())); ASSERT_EQUALS(80, foo.*get(tested_class_i())); return 0; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload