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

我基本上不确定BlobBulbasaurTrainingCamp. 我的期望是每个BulbasaurcrapB_Blob. 我希望 C++ 会真正做看似明智的事情。这是一个例子,“它可以编译,所以我认为我应该很高兴,但我仍然不能完全确定它正在做我认为应该做的事情”。

4

3 回答 3

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。我希望这个例子能有所帮助。

于 2013-08-26T04:31:28.540 回答
0

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

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

  1. 不要在基类中放置任何有意义的代码或数据;将其保留为纯界面。这可能会导致代码重复(但您可以将其分解到新的基类或共享辅助函数中)。
  2. 使用动态大小的容器类型作为Blob,因此您可以在构造函数中动态地请求更多或更少的空间。
  3. Blob创建一个单独的继承层次结构(例如B_Blob,从分配了不同空间量S_Blob的抽象继承),其中包含一个返回要使用的虚函数。BlobAbstractBlob
于 2013-08-26T04:20:29.300 回答
0

您似乎以某种方式假设此代码使用 C++ 编译。它当然不会。即使在修补了各种 C++/CLI 细节之后,a 仍然Blob没有调用数据成员moreData,并且获得它的唯一方法(使用 C++)是使用合适的强制转换。

这些BulbasaurTrainingCamp对象将有两个名为的成员allTheStuff,一个是 type Blob,一个是 type B_Blob。你得到哪一个取决于你正在查看的类型(因为所有成员都是私人的,你不会得到任何,但让我们忽略这个细节)和/或你使用的资格:

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

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

也就是说,当使用看起来像 a 的东西时,BulbasaurTrainingCamp您可以同时访问 theBlobB_Blob对象,但您需要使用限定来访问AbstractsallTheStuff成员。使用 an 时,Abstract您只能访问AbstractsBlob对象。

于 2013-08-26T04:25:33.370 回答