2011-03-27 98 views
1

當我試圖設計交互類時,我對一些問題感到困惑。班級互動技巧

如果一個類A需要來自類B的一些數據,無論是以指針還是標準容器格式(甚至讓我們變得更加雄心勃勃,並以一些shared_ptr成員的形式來表示stl容器),我的方法是使用返回相同類型參數的函數,並使用符合參數設計類B方法?設計交互類和共享這些類之間的數據是否有一個通用的經驗規則? 您能否爲實踐中普遍遇到的一些常見情況繪製一個通用方案(並且讚賞一些例子)?我想我應該閱讀一些關於C++中的類交互的例子,對此的任何指針也都很感激?

一個小樣本可能是:

#include <iostream> 
#include <vector> 
#include <iterator> 
#include <cassert> 

using namespace std; 

class A{ 
    public: 
     A(int s, int val):sz(s), val(val), v(new vector<int>){} 
     int fill_vector(){ 
      for(int k=0;k!=sz;++k) 
      v->push_back(val); 
      return 0; 
     }  
     ~A(){ 
      cout << "Dtor is deleting the pointer to vector\n"; 
      delete v; 
     }  
     vector<int>* get_pointer_to_vector_in_A(){ return v; } 
    private: 
     int sz, val; 
     vector<int> *v; 
}; 

class B{ 
    public: 
     B(){} // does nothing basically 
     int print_vector_contents_from_A(vector<int> *v_from_A) const 
     {  
      assert(!v_from_A->empty()); 
      copy(v_from_A->begin(), v_from_A->end(), 
       ostream_iterator<int>(cout, "\n")); 
     } 
}; 

int main() 
{ 
    A a(10, 4); 
    a.fill_vector(); 
    B b; 
    b.print_vector_contents_from_A(a.get_pointer_to_vector_in_A()); 
    return 0; 
} 

回答

0

它,而要看是什麼A是,在概念上。如果A可以有效地看作是int的一個序列,那麼我會在其上執行size_t size() constint &operator[](size_t)(+其const對應部分)。這些可以將他們的活動委託給v.sizev[]v.at

B,然後你可以定義

static void B::print_contents(A const &a) 
{ 
    for (size_t i=0; i < a.size(); i++) 
     std::cout << a[i] << '\n'; 
} 

返回一個std::vector<int>*休息封裝成員:你永遠無法從std::vector<int>改變A實施外,除非有非常難看黑客,以確保get_pointer_to_vector_in_A仍然有效用相同的語義。

+0

謝謝,實際上問題的根源來自於我應該以某種方式共享一些以矢量形式存在的數據。我想我理解你的觀點,對於封裝來說,然而對於這個實現,這不是一個模板類,所以即使在這種情況下,如果我使用向量,封裝就會被破壞。我的意思是,我確實通過A的功能達到了這個目的...... – 2011-03-27 14:48:21

+0

由於您通過界面公開了實現細節,因此封裝被破壞。除了'std :: vector'以外,'A'不能有效地實現,因爲它是它的輸出。 – 2011-03-27 14:49:57

+0

「封裝被破壞,因爲你通過接口公開實現細節」對我來說不是很清楚,我發現我使用的是std :: vector,這是封裝破壞嗎?你的意思是我應該使用一個typedef左右,或者像你在你的代碼中做的那樣,把額外的重載操作符隱藏實現細節?我想我對封裝有一個概念誤解,現在我想這很明顯。 – 2011-03-27 14:52:30

0

一個偉大的單向方式來做到這一點是:

class A { 
public: 
    void fill_vector(); 
    int vec_size() const { return vec.size(); } 
    int get_data(int i) const { return vec[i]; } 
}; 
class B { 
public: 
    B(A &a) : a(a) { } 
    void init() { a.fill_vector(); } 
    void fetch_and_print() 
    { for(int i=0;i<a.vec_size();i++) std::cout << a.get_data(i); } 
private: 
    A &a; 
}; 
int main() { 
    A a; 
    B b(a); 
    b.init(); 
    b.fetch_and_print(); 
} 

B類的構造函數的參數是最重要的一點。