C++ 基类中的抽象基成员变量

C++ 基类中的抽象基成员变量,c++,c++11,C++,C++11,我想指定一个接口,它需要一个抽象类将某个类型作为成员变量 我将尝试在这里复制这种情况: 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 s

我想指定一个接口,它需要一个抽象类将某个类型作为成员变量

我将尝试在这里复制这种情况:

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"));
    }
}
类Blob{
int数据[32];
};
班主任{
字符串名;
抽象空区(Blob&)=0;
}
类摘要{
向量工作列表;
所有的凝灰岩;
抽象void somethingElse()=0;
无效完成所有工作(){
for(w:工人列表){
w->修井(所有凝灰岩);
}
}
};
B类Blob:公共Blob{
int moreData[4096];
};
BulbasaurTrainingCamp课程:公开摘要{
一团一团的乱麻;
void somethingElse(){}//已实现
//本课程将接受Bulbasaurs进入workerList
};
Bulbasaur班:工人{
Bulbasaur():名称(“Fushigidane”){}
无效作业(Blob&b){
//bulbasaurs用垃圾覆盖了他们所有的工作空间

对于(int i=0;i基类,即使是抽象类,也将被完整地包含在任何派生类中。新的
allthestaff
名称隐藏了旧的名称,但不抑制其包含;基类版本仍然可以使用
abstract::allthestaff
访问。更糟糕的是,函数
将完成所有工作访问基类
allthestaff
,因为它不可能知道子类中存在同名的成员变量

如果你想要这种行为,你有几个不错的选择:

  • 不要在基类中放入任何有意义的代码或数据;将其作为纯接口保留。这可能会导致代码重复(但您可以将其分解为新的基类或共享的辅助函数)
  • 使用可动态调整大小的容器类型作为
    Blob
    ,以便可以动态请求构造函数中的更多或更少空间
  • 使
    Blob
    成为一个单独的继承层次结构(例如
    B_Blob
    S_Blob
    从分配了不同空间量的抽象
    Blob
    继承),在
    abstract
    中使用一个虚拟函数,返回要使用的
    Blob

  • 基类,甚至是抽象类,都将被完整地包含在任何派生类中。新的
    allthestaff
    名称隐藏了旧的名称,但不会抑制其包含;基类版本仍然可以使用
    abstract::allthestaff
    访问。更糟糕的是,函数
    doAllTheWork
    将最终访问基类
    allthestaff
    ,因为它不可能知道子类中存在同名的成员变量

    如果你想要这种行为,你有几个不错的选择:

  • 不要在基类中放入任何有意义的代码或数据;将其作为纯接口保留。这可能会导致代码重复(但您可以将其分解为新的基类或共享的辅助函数)
  • 使用可动态调整大小的容器类型作为
    Blob
    ,以便可以动态请求构造函数中的更多或更少空间
  • 使
    Blob
    成为一个单独的继承层次结构(例如
    B_Blob
    S_Blob
    从分配了不同空间量的抽象
    Blob
    继承),在
    abstract
    中使用一个虚拟函数,返回要使用的
    Blob

  • 你似乎在假设C++使用C++编译。即使在修补了各种C++和CLI细节之后,仍然存在一个<代码> BLUB<代码>没有一个数据成员叫做“代码> MordaDaa/Cudio>。

    BulbasaurTrainingCamp
    对象将有两个名为
    allthestaff
    的成员,一个是
    Blob
    类型,另一个是
    B\u Blob
    类型。获得哪一个取决于查看的类型(因为所有成员都是私有的,所以不会获得任何成员,但我们忽略该细节)和/或您使用的资格:

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

    也就是说,当使用看起来像
    bulbasourtrainingcamp
    的东西时,您可以访问
    Blob
    B_Blob
    对象,但您需要使用限定来访问
    Abstract
    s
    所有成员。当使用
    Abstract
    时,您只能访问
    Abstract
    s
    < Bulb>代码> > /p> > p>你似乎在假设C++使用C++编译。即使在修补了各种C++和CLI细节之后,仍然存在一个<代码> BLUB<代码>没有一个数据成员叫做<代码> MordEdAt/Cudio>。
    
    #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;
    }
    
    BulbasaurTrainingCamp
    对象将有两个名为
    allthestaff
    的成员,一个是
    Blob
    类型,另一个是
    B\u Blob
    类型。获得哪一个取决于查看的类型(因为所有成员都是私有的,所以不会获得任何成员,但我们忽略该细节)和/或您使用的资格:

    BulbasaurTrainignCamp btc;
    B_Blob&               b_blob = bts.allTheStuff;
    Blob&                 blob1  = bts.Abstract::allTheStuff;
    
    Abstract& abstract;
    Blob&     blob2 = abstract.allTheStuff;
    
    也就是说,当使用看起来像
    bulbasourtrainingcamp
    的东西时,您可以访问
    Blob
    B_Blob
    对象,但您需要使用限定来访问
    Abstract
    s
    所有成员。当使用
    Abstract
    时,您只能访问
    Abstract
    s
    >Blob
    对象。

    #包括
    
    #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;
    }
    
    #包括 使用名称空间std; int main() { 阶级基础 { 公众: int sameName; 基(intx):sameName(x){} }; 派生类:公共基 { 公众: int diffName; int sameName; 派生(intx,inti,intj):基(x),diffName(i),sameName(j){ }; 衍生示例(1,2,3); 不能包含 #包括 使用名称空间std; int main() { 阶级基础 { 公众: int sameName; 基(intx):sameName(x){} }; 派生类:公共基 { 公众: 因特迪夫南酒店