2015-09-17 69 views
-2

這裏就是我試圖完成:提供函數指針訪問C++類的私有成員 - 是否有可能?

- 客戶端與類(富)註冊一個函數(FUN)

-fun具有一般形式類型函數(INT,INT,INT)

- 然後,在執行其工作時,調用該函數,這可能需要訪問私有成員

關鍵是允許Foo可以在其工作過程中使用的用戶定義函數。有沒有C++的模式/細微差別等等,這會使這可行嗎?

最糟糕的情況我可以公開數據,但我很好奇如果有更好的東西存在。

TIA

實施例:

class foo; 

typedef float (*client_fun)(foo &obj, int &i); 
class foo 
{ 
    client_fun their_fun; 

    int private_info; 

public: 
    foo(): private_info(42){}; 

    void set_fun(client_fun _fun) 
    { 
     their_fun = _fun; 
    } 

    float run_foo() 
    { 
     //Oversimplified example of what it would be doing. 
     //their_fun would be called as part of a complicated method 
     int i; 
     i = 1; 
     return their_fun(*this, i); 
    } 

}; 

float fancy_fun(foo &obj, int &i) 
{ 
    //needs access to private info 
    return (i/obj.private_info); 
} 

int main() 
{ 
    //Hypothetical use 
    foo my_foo; 

    my_foo.set_fun(fancy_fun); 

    //Can't access the private member 
    my_foo.run_foo(); 

    return 0; 
} 

G ++ example.cpp:

example.cpp: In function ‘float fancy_fun(foo&, int&)’: 
example.cpp:8:8: error: ‘int foo::private_info’ is private 
    int private_info; 
     ^
example.cpp:32:18: error: within this context 
    return (i/obj.private_info); 
+3

使功能成爲朋友...?我錯過了什麼嗎?聽起來像是一個破碎的設計,儘管如果你需要外部函數來獲得一個類型的內部訪問權限。如果類型具有公共接口,那麼公共接口應該是公共的。 –

+2

該函數如何知道該類的私有變量? – NathanOliver

+1

你真的嘗試過嗎?這裏沒有明顯的問題。發佈不起作用的代碼。 –

回答

0

這是回答我的問題的模式。

#include <iostream> 

class engine; 

class settings 
{ 
    //Can friend the engine class if we have private members we want to be able to call 
    friend class engine; 

public: 
    int private_info; 
    settings() 

    { 
     private_info = 42; 
    }; 
}; 

typedef float (*fn_ptr)(settings &); 

class engine 
{ 
    //private info will still be private to the world since the engine owns the settings object 
    settings my_settings; 
    fn_ptr my_fn; 

public: 

    engine(): my_settings(){}; 

    void set_fun(fn_ptr _ptr) 
    { 
     my_fn = _ptr; 
    } 

    void run() 
    { 
     std::cout << my_fn(my_settings, 1) << "\n"; 
    } 
}; 


float fancy_fun(settings &obj, size_t i) 
{ 
    //needs access to private info 
    return (obj.private_info); 
} 

int main() 
{ 
    //Hypothetical use 
    engine my_engine; 

    my_engine.set_fun(fancy_fun); 


    //Error! Private! 
    //my_engine.my_settings; 

    /*Is now accessing the public member of a private object 
    * using an appropriately specified user function */ 
    my_engine.run(); 

    return 0; 
}