2013-08-26 4 views
1

추상 클래스가 특정 유형을 멤버 변수로 갖도록 요구하는 인터페이스를 지정하려고합니다. 여기기본 클래스의 추상 기본 변수

class Blob { 
    int data[32]; 
}; 
class Worker { 
    string name; 
    abstract void workOn(Blob&) = 0; 
} 

class Abstract { 
    vector<shared_ptr<W>> workerList; 
    Blob allTheStuff; 
    abstract void somethingElse() = 0; 
    void doAllTheWork() { 
    for (w : workerList) { 
     w->workOn(allTheStuff); 
    } 
    } 
}; 

class B_Blob : public Blob { 
    int moreData[4096]; 
}; 

class BulbasaurTrainingCamp : public Abstract { 
    B_Blob allTheStuff; 
    void somethingElse() {} // implemented 
    // this class will accept Bulbasaurs into workerList 
}; 

class Bulbasaur : Worker { 
    Bulbasaur(): name("Fushigidane") {} 
    void workOn(Blob& b) { 
    // bulbasaurs cover *all* their workspace with crap 
    for (int i=0; i<sizeof(b.data[0])/sizeof(b.data); ++i) { 
     b.data[i] = *((int*)&("crap")); 
    } 
    for (i=0; i<sizeof(b.moreData[0])/sizeof(b.moreData); ++i) { 
     b.moreData[i] = *((int*)&("crap")); 
    } 
} 

는, 추상 BAS 클래스는 Blob을 가지고 있지만 BulbasaurTrainingCamp의 인스턴스가 파생 B_Blob 있습니다

여기 상황을 복제하려고합니다. 동일한 이름을 부여한 이후로 컴파일러는이를 수용합니다.

이름이 있습니까? 내가 알기를 원하는 것은 내가 이것을 할 때의 행동이다. BlobB_Blob으로 재정의 했습니까?

기본적으로 액세스 할 수없는 기본 Blob 인스턴스가 BulbasaurTrainingCamp 안에 매달려 있는지 여부는 확실하지 않습니다. 내 기대는 각각 BulbasaurB_Blob의 두 멤버 변수에 걸쳐 crap의 16512 (16384 아님) 바이트를 씁니다. 나는 C++이 실제적으로 합리적인 것으로 보이는 것을하기를 바라고 있습니다. 그것은 "내가 행복해 져야한다고 생각하기 때문에 컴파일된다. 그러나 나는 여전히 그것이해야한다고 생각하는 것을 완전히 확신하지 못한다"는 경우이다.

+0

C++ 코드에서 '추상적'을 사용할 수 있다는 것을 알지 못했습니다. –

+0

나는 몰라. 어쩌면 빠져 나갈 수 있을까요? 나는 항상 클래스가 인스턴스화 될 수 없다는 신호를 보내 왔습니다. –

+0

@ DietmarKühl 뉴스 또한 "이것은 .NET 프레임 워크의 C++/CLI 언어 구체화의 일부로 도입 된 키워드입니다." http://stackoverflow.com/questions/1298093/can-i-use-abstract-keyword-in-c-class –

답변

0

기본 클래스 (추상 클래스도 포함)는 파생 클래스 내에서 전체적으로 포함됩니다. 새 allTheStuff 이름은 이전 이름을 숨기지 만 포함하지는 않습니다. 베이스 클래스 버전은 여전히 ​​Abstract::allTheStuff을 사용하여 액세스 할 수 있습니다. 더욱이 함수 doAllTheWork은 하위 클래스에 동일한 이름의 멤버 변수가 있다는 것을 알 수 없으므로 기본 클래스 allTheStuff에 액세스하게됩니다. 당신은 행동의이 종류를 원하는 경우

, 당신은 몇 가지 괜찮은 옵션이

  1. 기본 클래스에서 의미있는 코드 나 데이터를 입력하지 마십시오 그것을 순수한 인터페이스로 남겨 두십시오. 이로 인해 코드가 중복 될 수 있습니다 (하지만 새로운 기본 클래스 또는 공유 도우미 함수로이를 배제 할 수 있음).
  2. 동적 크기가 큰 컨테이너 유형을 Blob으로 사용하면 생성자에서 더 많은 또는 더 적은 공간을 동적으로 요청할 수 있습니다.
  3. Blob에게 별도의 상속 계층 구조를 확인합니다 (예를 들어, B_Blob 및 할당 된 공간의 양을 다른와 추상적 인 Blob에서 S_Blob 상속)을 사용하는 Blob 반환 Abstract에서 가상 기능.
0

어떻게 든이 코드는 C++를 사용하여 컴파일된다고 가정합니다. 확실히 그렇지 않습니다. 다양한 C++/CLI 관련 패치를 적용한 후에도 Blob에는 moreData이라는 데이터 멤버가 없으며 C++을 사용하는 유일한 방법은 적절한 캐스트를 사용하는 것입니다.

BulbasaurTrainingCamp의 개체에는 유형과 B_Blob 유형 중 하나 인 allTheStuff이라는 두 개의 멤버가 있습니다.당신이 얻을 어느 하나에 당신이보고있는 유형에 따라 (모든 회원은 개인이기 때문에, 당신은 어떤을 얻을 수 있지만, 이제 그 세부 무시하지 않습니다) 사용 및/또는 어떤 자격 :

BulbasaurTrainignCamp btc; 
B_Blob&    b_blob = bts.allTheStuff; 
Blob&     blob1 = bts.Abstract::allTheStuff; 

Abstract& abstract; 
Blob&  blob2 = abstract.allTheStuff; 

입니다, BulbasaurTrainingCamp과 같은 것을 사용할 때 BlobB_Blob 개체에 모두 액세스 할 수 있지만 회원에 액세스하려면 자격을 사용해야합니다. Abstract을 사용할 때 오브젝트에만 액세스 할 수 있습니다.

1
#include<iostream> 
#include<vector> 
using namespace std; 

int main() 
{ 
    class base 
    { 
    public: 
     int sameName; 
     base(int x):sameName(x){} 
    }; 
    class derived : public base 
    { 
    public: 
     int diffName; 
     int sameName; 
     derived(int x,int i,int j):base(x),diffName(i),sameName(j){} 

    }; 
    derived example(1,2,3); 
    cout<<example.sameName<<endl; 
    cout<<example.diffName<<endl; 
    cout<<example.base::sameName<<endl; 
} 

결과는 내가 예제가 도움이 될 수있는 희망 3 2 1 입니다.

관련 문제