2012-07-09 3 views
-3
#define classAnum 2; 
#define classBnum 3; 

class Base 
{ 
    virtual int open()=0; 
    virtual int close()=0; 
} 
class A:public Base 
{ 
virtual int open(); 
virtual int close(); 
}; 

class B:public Base 
{ 
virtual int open(); 
virtual int close(); 
} 

int main() 
{ 
    A classA[classAnum]; 
    B classB[classBnum]; 

openAnyClass(1); 
CloseAnyClass(2); 
} 

나는 이와 같은 기능을 원합니다.C++ 여러 클래스에있는 함수 호출

openAnyClass(1); 
CloseAnyClass(2); 

이들 두 기능은 클래스 A의 어떠한 B.에서() (개방) 및 확대를 호출 할 수 있어야

openAnyClass (1)의 1 개체의 개방() 함수를 호출 할 classA 또는 classB의 배열

open() -> 클래스 A와 클래스 B에서 서로 다른 구현을 가지며 클래스 A에서 open()을 여러 클라이언트와 max에서 호출 할 수 있습니다. 아니. 클라이언트가 # 정의되어 있습니다.

한 번에 하나의 open() 만 classA 또는 classB에서 호출됩니다. 나는 같은 코드의 여러 복사본을 갖고 싶지 않다.

저는 하나의 클래스 A와 클라이언트 중 하나의 open()을 호출하고 싶습니다.

예 : 아래 문에서 나는 client1의 클래스 A의 open()을 호출하려고합니다. openAnyClass (int)의 파라미터는 클라이언트 ID를 나타냅니다. 이는 또한 classB[1].open();

'openAnyClass(1) = classA[1].open();' 

을 의미 할 수 있습니다.

+0

동일한 메소드를 다른 방법으로 구현할 수 없습니다. 여러 개의 open() 함수가 무엇입니까? openAnyClass를 호출 할 때 Base (포인터가 클래스 A 또는 클래스 B의 인스턴스에서 상영 됨)에 포인터/참조를 전달하면이 포인터/참조에서 열기 또는 닫기를 호출 할 수 있으며 "자동으로"올바른 메소드가됩니다. "진짜"클래스에 따라 A :: open() 또는 B :: open()이 호출 됨 –

+2

@ user1511617'openAnyClass()'및'closeAnyClass()'의 매개 변수는 무엇을 의미합니까? –

+0

그래서 classA는 A의 배열이고 classB의 배열입니다. openAnyClass (1)을 호출하면 A의 모든 인스턴스에서 open()을 호출하고 closeAnyClass()는 classB의 모든 인스턴스에서 close()를 호출한다는 것을 의미합니다. 이것이 사실이라면, 질문은 정말로 공식화 된 복잡합니다. –

답변

1

당신이 파생 한 명령 기본 클래스가있는 이유는 다음과 같습니다. 그런 식으로 포인터 또는 클래스에 대한 참조를 가질 수 있고 가상 함수를 통해 파생 클래스에서 open/close 메서드를 호출 할 수 있습니다.

당신은했다 그렇다면

Base *generic_class_pointer = new class A(); 

generic_class_pointer->open(); 

개방>을 generic_class_pointer-() 클래스 A에 정의 된 코드를 호출 할

당신이 개체를 저장 두 배열, 하나하려고 노력하고 있습니다 클래스 A와 클래스 B에 대한 하나의 클래스가 필요하지 않은 경우 Base 유형의 클래스를 참조하는 단일 배열을 가질 수 있으며이를 통해 액세스 할 수 있습니다.

원래 코드는 실제로 작동하는 좋은 방법이 아니므로 목록 (예 : stl::vector)을 통해 이렇게하는 것이 좋습니다. 경우에 파생 클래스가 정리를 할 필요가 -

Base* class_storage[StorageSize]; 

int openAnyClass(int id) 
{ 
    if (id < 0 || id >= StorageSize || class_storage[id] == 0) 
     return 0; // or other error indication 
    else 
     return class_storage[id]->open(); 
} 
int CloseAnyClass(int id) 
{ 
    if (id < 0 || id >= StorageSize || class_storage[id] == 0) 
     return 0; // or other error indication 
    else 
     return class_storage[id]->close(); 
} 


int main() 
{ 
    memset(class_storage,0,sizeof(class_storage)); 

    class_storage[1] = new A(); 
    class_storage[2] = new B(); 

    openAnyClass(1); 
    CloseAnyClass(2); 
} 

위의 코드는 원래 항상 사용하는 것이 좋습니다 가상 소멸자가없는 예를 들어 완벽한 솔루션 아니다.

또한 class_storage에 할당 된 개체의 삭제는 내 샘플에서 해제되지 않습니다. 글로벌 수준에서는 문제가되지 않습니다. 왜냐하면 출구에서 해제되기 때문에 대부분의 경우 new()을 통해 획득 한 모든 것을 관리해야합니다. 그렇지 않으면 메모리 누수가 발생합니다.

+0

전역 배열의 요소가 자동으로 기본값 초기화되므로 memset 호출이 불필요합니다. 그럼에도 불구하고, 'Base class_storage [StorageSize] = {0};은 어쨌든 초보자에게 더 좋을 것입니다. – mloskot

+1

오브젝트를'new'로 할당해야한다면, 삭제하거나 스마트 포인터를 사용하여 오브젝트를 관리해야합니다. 가상 소멸자도 거의 필요합니다. –

+0

openAnyClass (1)는 classA 또는 classB 배열에서 첫 번째 객체의 open() 함수를 호출합니다. – Fancier

0

그래서 classA는 A의 배열이고 classB의 배열입니다. openAnyClass (1)을 호출하면 A의 모든 인스턴스에서 open()을 호출하고 closeAnyClass()는 classB의 모든 인스턴스에서 close()를 호출한다는 것을 의미합니다. 만약 그렇다면 질문은 실제로 복잡하게 만들어진 것입니다.

어쨌든 알기 쉬운 방법은 없습니다. 배열의 모든 요소를 ​​반복하고 open() 또는 close()를 호출해야합니다.또는 당신은 부스트의 foreach에게 http://www.boost.org/doc/libs/1_39_0/doc/html/foreach.html 를 사용하거나 내가 정확히, 당신은 순수 가상 함수의 다른 구현을 호출 할 질문을 이해한다면 자신의 foreach는 방법

0

을 구현할 수 있습니다. 클래스 A와 클래스 B의 구현을 제공한다고 가정하면 polymorphism을 사용하고 A 또는 B 대신 포인터/참조에서 open()/close()를 호출 할 수 있어야합니다.

A와 B에 대해 두 개의 배열을 만들면 하나의 기본 포인터 배열 만 만들 수 있습니다.

예 :

보조 노트, 나는 이와 같은 개폐 기능을 사용하기 위해 더 좋을 거라 생각으로
Base* base[basenum]; 

void openAnyClass(const int i) 
{ 
    if(i < basenum && i >=0 && base[i] != NULL) 
     base[i]->open(); 
} 

int main(void) 
{ 
    base[0] = new A(); 
    base[1] = new B(); 
    ... 
    openAnyClass(1); 
    closeAnyClass(2); 

    for(int i = 0 ; i < basenum ; i++) 
     delete base[i]; 
} 

:

void openAnyClass(Base& base); 
void closeAnyClass(Base& base); 

보다는 저장하는 전역 변수를 사용하여 객체를 전달하고 색인을 전달하고, 객체의 포인터/참조를 함수에 전달하면 함수는 적절한 메소드 (A 또는 B의 메소드)를 호출합니다.

+0

이 접근법을 사용한다면 C 스타일 배열보다는'벡터 베이스 '를 만들고'i <= base.size()'를 반복하면서'delete' 루프를 수정하십시오. 지금 할당되지 않은 포인터를 삭제하는 중일 수 있습니다 ... –