我想知道 如何 使用引用而不是指针来进行多态性。
为了澄清,请参阅以下最小示例:
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
) {
}
这可以编译并且可以工作,但是这里最重要的一点是 a
行 #1
是一个参考,所以为了能够多态地使用它(这是一个实际的词?),如 #3
行所示,我必须通过取消引用来“将指针转换为引用”。
这让我觉得有点奇怪,我想知道是否有更好的(在 更清洁 的意义上)方法。只有我吗?
基本原理
如果我根本不需要 new
了,但是当声明(!)时 B
我不知道如何创建一个实例 A1
(!) as A
是前向声明 A1
在与 B
相同的编译单元中实现。不过,在这种情况下是否真的需要动态内存分配?你会怎么做?
抱歉,有点双重问题。
编辑
注意: B
很大(我无法为其创建模板类),并且会在程序终止时准确超出范围 a
很小,可以制作两个大模块互相交谈,只要 B
的实例存在(只有一个),就需要它。
编辑 2
I just realised, that since both A
and B
are effectively singletons, I can simply create a static
instance of A1
in the compilation B
的单位,避免动态内存分配(即使有两个 B
他们可以轻松地使用相同的实例 A
)。公平地说,我没有将此作为答案发布,但会接受促使我提出此 解决方案 的答案。
原文由 bitmask 发布,翻译遵循 CC BY-SA 4.0 许可协议
没有什么奇怪的。多态性适用于指针 和 引用:
您将此与另一个问题混为一谈,即创建对动态对象的引用:
请注意, 仅 通过引用跟踪动态对象通常是非常糟糕的风格,因为删除它的唯一方法是通过
delete &x;
,而且很难看到x
需要清理.There are two immediate alternatives for your design: 1) make
a
a member object inB
, or 2) makea
ashared_ptr<A>
或unique_ptr<A>
并将初始化程序更改为a(new A1)
。这完全取决于您是否真的需要多态行为,即如果您有其他构造函数B
将不同的派生类分配给a
除了A1