2011-03-27 9 views
1

상호 작용하는 클래스를 디자인 할 때 몇 가지 문제에 당황 스럽습니다.클래스 상호 작용 도움말

클래스 A가 포인터 또는 표준 컨테이너 형식의 형식으로 클래스 B의 일부 데이터를 필요로하거나 (심지어 더 야심적이되어 일부 shared_ptr 멤버의 형식으로 stl 컨테이너에 있다고해도), my 같은 종류의 인수를 반환하는 함수를 사용하고 클래스 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이 무엇인지에 따라 달라집니다. Aint의 시퀀스로 유효하게 표시 될 수 있다면 및 int &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>* 휴식 캡슐화를 반환하는 멤버를 정의 할 수 있습니다 : 당신은 여전히 ​​작동 get_pointer_to_vector_in_A을 보장하기 위해 매우 추한 해킹 제외 std::vector<int>에서 멀리 A의 구현을 변경할 수 없다 동일한 의미론. 이 작업을 수행하는

+0

감사합니다. 실제로 질문의 출처는 어떻게 든 벡터 형태의 데이터를 공유해야한다는 사실에서 비롯됩니다. 캡슐화에 대한 귀하의 요점을 이해하는 것 같아요,하지만이 구현에 대한 템플릿 클래스가 아니어도 그 경우에도 벡터를 사용하면 캡슐화가 끊어지는 것이 맞습니까? 나는 A의 기능을 통해 그 목표를 달성한다는 것을 의미한다 ... –

+0

구현 세부 사항을 인터페이스를 통해 노출하기 때문에 캡슐화가 깨진다. 'A'는'std :: vector'가 아닌 다른 것으로 효율적으로 구현 될 수 없습니다. 왜냐하면 그것은 그것이 수출하는 것이기 때문입니다. –

+0

"캡슐화가 인터페이스를 통해 구현 세부 사항을 노출했기 때문에 캡슐화가 깨졌습니다."내가 밝히는 것은 내가 표준 : : 벡터를 사용한다는 것입니다. 캡슐화가 깨지십니까? 그리고 typedef를 사용해야한다는 것을 의미합니다. 또는 코드에서했던 것처럼 오버로드 된 연산자를 추가하여 구현 세부 사항을 숨길 수 있습니까? 캡슐화에 대한 개념적 오해가 있었을 것 같아요. 분명히 추측 할 수 있습니다. –

0

하나의 큰 하나의 방향 방법입니다 : 클래스 B에 대한

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(); 
} 

생성자 매개 변수가 중요한 비트입니다.