多态C++引用

bit*_*ask 21 c++ polymorphism reference

我想知道如何使用引用进行多态性,而不是指针.

为了澄清,请参阅以下最小示例:

class A;

class B {
  public:
    A& a; ///////////////// <- #1
    B();
    void doStuff();
};

class A {
  public:
    virtual void doSmth() = 0;
};
void B::doStuff() {
  a.doSmth();
}

class A1 : public A {
  public:
    void doSmth() {
    }
};

B::B() : a(
    *        ////////////// <- #2
      (new A1)  /////////// <- #3
     ) {
}
Run Code Online (Sandbox Code Playgroud)

这个编译和工作,但这里最重要的一点是,a在行中#1是一个引用,所以为了能够多态地使用它(是一个真正的单词?),如行#3I 所示必须"转换指针参考"通过解除引用它.

这让我觉得有点奇怪,我想知道是否有更好的(在更清洁的意义上)方式.只有我吗?

合理

如果我根本不需要它会很好new,但是当声明(!)时B我不知道如何创建A1(!)的实例和A正向声明 - A1在同一个编译单元中实现B.在这种情况下,是否真的需要动态内存分配?你会怎么做?

对不起,这个问题有点双重.

编辑

注意:B是巨大的(我不能制作它的模板类),并且在程序终止时会精确地超出范围 - a很小并且使两个大模块相互通信,只要实例就需要它的B生活(只有一个).

编辑2

我刚刚意识到,因为两者AB是有效的单身人士,我可以简单地创建一个static实例A1中的编译单元B,避免了动态内存分配(即使有两个B就是他们可以很容易地使用相同的实例A).公平地说,我没有将此作为答案发布,但会接受促使我提出这个解决方案的答案.

Ker*_* SB 35

没有什么奇怪的.多态性适用于指针引用:

struct Base { };
struct Derived : Base;

void foo(Base &);

int main() {
  Derived x;
  foo(x);    // fine
}
Run Code Online (Sandbox Code Playgroud)

您将此与另一个问题混为一谈,即创建对动态对象的引用:

T * pt = new T;
T & rt = *pt;

T & x = *new T;  // same effect
Run Code Online (Sandbox Code Playgroud)

请注意,通过引用跟踪动态对象通常是非常糟糕的样式,因为删除它的唯一方法是通过delete &x;,并且很难看到x需要清理.

有您的设计两个直接选择:1)使a对象的一个成员中B,或2)使a一个shared_ptr<A>unique_ptr<A>并更改initalizer来a(new A1).这一切都取决于你是否真的需要多态行为,即如果你有其他的构造B,其分配一个不同的派生类a以外A1.