Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[C++/STL] pointer to member function!? about …

0 views
Skip to first unread message

御風只配做笨木頭

unread,
Apr 24, 2000, 3:00:00 AM4/24/00
to
※ 引述《jjho...@bbs.cs.nthu.edu.tw (jjhou)》之銘言:
: // vc6[o] bcb4[o] g++2.91.57[o]
: #include <map>
: #include <string>
: using namespace std;
: // BCB 要求需先有 typedef. (不合理的要求)
: // VC6 和 G++ 允許直接為 map 指定 type of pointer to member function.
: class A {
: typedef bool (A::*MemFuncPtr)(char);
: map<string, MemFuncPtr> table;
: };
: int main()
: {
: }
: -- jjhou

正巧跟學弟在討論 BCB 的 __property 怎樣用 standard 的方法 implement。
我寫了下面這段 code(明天計組期中考 :~~~):

=====================================================================
% more property.cc
#include <iostream>
#include <cstring>

using namespace std;


template <typename BASE, typename T>
class property
{
public:
typedef T (BASE::*RMemFuncPtr)();
typedef void (BASE::*WMemFuncPtr)(T&);


property () {}

property (BASE* me, RMemFuncPtr rf, WMemFuncPtr wf)
: _me(me), _rfunc(rf), _wfunc(wf) { }

// 用這個 ctor 會掛點... :<

void setup(BASE* me, RMemFuncPtr rf, WMemFuncPtr wf) {
_me = me;
_rfunc = rf;
_wfunc = wf;
}

property& operator = (T rhs) {
(_me->*_wfunc)(rhs);
return *this;
}

operator T () {
return (_me->*_rfunc)();
}

private:
BASE* _me;
RMemFuncPtr _rfunc;
WMemFuncPtr _wfunc;

};

class Test
{
public:

Test() {
Cnum.setup(this, &Test::RNum, &Test::WNum);
}

char* RNum() {
cerr << "Test::RNum called" << endl;
return const_cast<char*>(tbl[Nnum]);
}

void WNum(char* &rhs) {
cerr << "Test::WNum called" << endl;
for (int i = 0; i < 10; ++i) {
if (!strcmp(rhs, tbl[i])) {
Nnum = i;
return;
}
}
Nnum = 0;
}

property<Test, char*> Cnum;
int Nnum;

private:

static const char* tbl[10];

};


const char* Test::tbl[10] = { "零", "一", "二", "三", "四",
"五", "六", "七", "八", "九", };

int
main(int argc, char* argv[])
{
Test atext;
char buf[] = "三";

atext.Cnum = buf;
cout << atext.Cnum;

return 0;
}

% g++ -v
Reading specs from /usr/local/lib/gcc-lib/i386-portbld-freebsd3.2/egcs-2.91.66/s
p
ecs

% g++ property.cc

% ./a.out
Test::WNum called
Test::RNum called

%
============================================================================

若是要使用 3 個參數的 ctor 版本的話(用起來才漂亮些),Test 變成:

============================================================================
class Test
{
public:

Test() {
// Cnum.setup(this, &Test::RNum, &Test::WNum);
}

char* RNum() {
cerr << "Test::RNum called" << endl;
return const_cast<char*>(tbl[Nnum]);
}

void WNum(char* &rhs) {
cerr << "Test::WNum called" << endl;
for (int i = 0; i < 10; ++i) {
if (!strcmp(rhs, tbl[i])) {
Nnum = i;
return;
}
}
Nnum = 0;
}

property<Test, char*> Cnum(this, &Test::RNum, &Test::WNum);
int Nnum;

private:

static const char* tbl[10];

};
============================================================================

然後 g++ 跟我這樣 complain:

============================================================================
% g++ property.cc
property.cc:67: invalid use of `this' at top level
property.cc:67: incomplete type `Test' does not have member `RNum'
property.cc:67: incomplete type `Test' does not have member `WNum'
property.cc:67: warning: ANSI C++ forbids initialization of member `Cnum'
property.cc:67: warning: making `Cnum' static
property.cc:67: ANSI C++ forbids in-class initialization of non-const static member `Cnum'
property.cc:67: initializer invalid for static member with constructor
property.cc:67: (you really want to initialize it separately)
============================================================================

請問侯老或版上的各位大大,這是怎樣的一個情形啊?
又,有可能避掉 _me 嗎?


ps.電腦裡沒灌 BCB 或 VC,不知道在 BCB 或 VC 底下,
這段程式碼會變成什麼樣子... :Q


--
※ Origin: 窈窕淑女 ◆ From: gentleman
--
※【窈窕淑女】telnet://lady.twbbs.org
http://lady.twbbs.org/~bbs/

0 new messages