polymorphic C++ references(多态 C++ 参考)
问题描述
我想知道如何使用引用而不是指针来实现多态性.
I was wondering how you can do polymorphism with references, as opposed to pointers.
为了澄清,请参见以下最小示例:
To clarify, see the following minimal example:
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
) {
}
这可以编译并且可以工作,但是这里最重要的一点是 #1
行中的 a
是一个引用,所以为了能够多态地使用它(这是一个实际的词吗?),如 #3
行所示,我必须将指针转换为引用";通过取消引用它.
This compiles and works, but as the most important point here is that a
in line #1
is a reference, so in order to be able to use it polymorphically (is that an actual word?), as shown in line #3
I have to "convert a pointer to a reference" by dereferencing it.
这让我觉得有点奇怪,我想知道是否有更好的(在 cleaner 的意义上)方法.只有我吗?
This strikes me as a bit odd, and I was wondering if there is a better (in the sense of cleaner) way. Is it just me?
如果我根本不需要 new
那就太好了,但是在声明 (!) B
时,我不知道如何创建 A1
(!) as A
是前向声明 - A1
与 B
在相同的编译单元中实现.不过,在这种情况下是否真的需要动态内存分配?你会怎么做呢?
It would be great if I didn't need a new
at all, but when declaring (!) B
I have no clue how to create an instance of A1
(!) as A
is a forward declaration -- A1
is implemented in the same compilation unit as B
. Still, is there a real need for dynamic memory allocation in this case? How would you do this?
抱歉,有点双重问题.
注意:B
很大(我不能为它创建一个模板类),并且会在程序终止时恰好超出范围——a
很小并使两个大模块相互通信,只要 B
的实例存在(只有一个)就需要它.
Note: B
is huge (and I cannot make a template class of it), and will go out of scope precisely when the program terminates -- a
is small and makes two big modules talk to each other, it will be needed as long as the instance of B
lives (there is only one).
我刚刚意识到,由于 A
和 B
都是有效的单例,我可以简单地创建 A1 的
在static
实例B
的编译单元中,避免动态内存分配(即使有两个B
也可以轻松使用相同的A<实例/代码>).公平地说,我没有将此作为答案发布,但会接受促使我提出此解决方案的答案.
I just realised, that since both A
and B
are effectively singletons, I can simply create a static
instance of A1
in the compilation unit of B
, avoiding dynamic memory allocation (even if there were two B
s they could easily use the same instance of A
). To be fair, I did not post this as answer, but will accept the answer that prompted me to come up with this solution.
推荐答案
没什么奇怪的.多态性适用于指针 和 引用:
There's nothing odd. Polymorphisms works both for pointers and references:
struct Base { };
struct Derived : Base;
void foo(Base &);
int main() {
Derived x;
foo(x); // fine
}
您将此与另一个问题混为一谈,即创建对动态对象的引用:
You're conflating this with another issue, namely creating a reference to a dynamic object:
T * pt = new T;
T & rt = *pt;
T & x = *new T; // same effect
请注意,通过引用仅跟踪动态对象通常是非常糟糕的样式,因为删除它的唯一方法是通过 delete &x;
,它是很难看出 x
需要清理.
Note that it's generally very bad style to track a dynamic object only by reference, because the only way to delete it is via delete &x;
, and it's very hard to see that x
needs cleaning up.
您的设计有两种直接的选择:1) 使 a
成为 B
中的成员对象,或 2) 使 a
成为 shared_ptr
或 unique_ptr
并将初始化器更改为 a(new A1)
.这完全取决于您是否真的需要多态行为,即您是否有 B
的其他构造函数将不同的派生类分配给 a
而不是 A1代码>.
There are two immediate alternatives for your design: 1) make a
a member object in B
, or 2) make a
a shared_ptr<A>
or unique_ptr<A>
and change the initalizer to a(new A1)
. It all depends on whether you actually need the polymorphic behaviour, i.e. if you have other constructors for B
which assign a different derived class to a
other than A1
.
这篇关于多态 C++ 参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:多态 C++ 参考
- 使用最流行的转义序列 1970-01-01
- 打印扩展的ASCII字符 1970-01-01
- C语言求模 1970-01-01
- C语言可使用的所有转义序列 1970-01-01
- “纯虚函数调用"在哪里?崩溃从何而来? 2022-10-18
- 使用整数值初始化char类型的变量 1970-01-01
- 使用来自float.h和limits的数据,找到该系统的一些 1970-01-01
- C++指向数组的指针 1970-01-01
- 运算符优先级 1970-01-01
- C++浮点常数 1970-01-01