首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多态C++引用

多态C++引用
EN

Stack Overflow用户
提问于 2011-08-25 14:24:54
回答 7查看 34.1K关注 0票数 29

我想知道如何使用引用(而不是指针)实现的多态性。

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

代码语言:javascript
复制
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是一个引用,所以为了能够在形式上使用它(这是一个实际的单词吗?),如行#3所示,我必须通过取消引用来“将指针转换为引用”。

这让我觉得有点奇怪,我想知道是否有更好的方法(在更清洁的意义上)。就我一个人吗?

基本原理

如果我根本不需要new,那就太好了,但是当声明(!) B时,我不知道如何创建A1 (!)的实例。因为A是一个前向声明不过,在这种情况下,是否真的需要动态内存分配?你会怎么做?

不好意思问了两个小问题。

编辑

注意:B是巨大的(我不能用它创建一个模板类),当程序结束时,a就会超出范围-- a很小,并且使两个大模块相互交谈,只要B存在(只有一个),就需要它。

编辑2

我刚刚意识到,由于AB实际上都是单例,所以我可以简单地在B的编译单元中创建A1static实例,从而避免动态内存分配(即使有两个B,它们也可以很容易地使用相同的A实例)。平心而论,我并没有把这个作为答案,而是会接受促使我想出这个解决方案的答案。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-08-25 14:28:03

没什么奇怪的。多态对指针和引用都有效:

代码语言:javascript
复制
struct Base { };
struct Derived : Base;

void foo(Base &);

int main() {
  Derived x;
  foo(x);    // fine
}

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

代码语言:javascript
复制
T * pt = new T;
T & rt = *pt;

T & x = *new T;  // same effect

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

您的设计有两个直接的替代方案: 1)使a成为B中的一个成员对象,或者2)使a成为shared_ptr<A>unique_ptr<A>,并将初始化器更改为a(new A1)。这完全取决于您是否实际需要多态行为,即如果您有其他的B构造函数,这些构造函数将一个不同的派生类分配给a,而不是A1

票数 47
EN

Stack Overflow用户

发布于 2011-08-25 14:29:59

,在这种情况下,是否真的需要动态内存分配?

不是的。只需先定义A1,然后使它成为B的正常成员。

多态对于引用和指针都很好。

票数 3
EN

Stack Overflow用户

发布于 2011-08-25 14:30:04

这实在是有点奇怪。如果您想要一个A1类型的成员变量(而不是一个引用),为什么不重新排列您的代码,使A1的定义出现在B的定义之前?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7192069

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档