【问题标题】:How to pass an interface object to a method?如何将接口对象传递给方法?
【发布时间】:2019-08-27 13:02:21
【问题描述】:

我需要将一个对象(定义为接口)传递给一个方法,但我不知道该怎么做。 该方法必须将此对象添加到地图中。显然,传递的对象将是接口 IFigure 的女儿。

void Drawing::addFigure(string id, IFigure figure) {
    drawings.insert(id, figure);
}

地图是这样定义的(在绘图类中):

map<string,IFigure> drawings;

感谢您的宝贵时间!

【问题讨论】:

  • 你的代码出了什么问题?
  • 查找“对象切片”
  • @dedecos 它要切片了。
  • 您可能需要map&lt;string,IFigure*&gt; drawings;map&lt;string,std::unique_ptr&lt;IFigure&gt;&gt; drawings;map&lt;string,std::shared_ptr&lt;IFigure&gt;&gt; drawings;(或map&lt;string,std::weak_ptr&lt;IFigure&gt;&gt; drawings;)之一
  • void Drawing::addFigure(string id, IFigure* figure)

标签: c++ dictionary methods interface


【解决方案1】:

您不能创建抽象类的实例。

所以声明:

IFigure figure;

这会构造一个新的IFigure。你不能那样做。

IFigure figure = Implementation{};

这也行不通。您正在通过复制切片的Implementation 创建一个新的IFigure。你也不能这样做。

变量是值,就像intIFigure figure 表示 IFigure 类型的值,而不是对实现的引用。它永远无法工作。

切片有点像这样问:

int i = double{1.6};
std::cout << i;
// Why does it prints '1'?? I assigned '1.6', it should refer to it!

当然,会发生转换,因此它会删除 .6 部分。就像切片删除 Implementation 部分以仅保留基类部分一样。


那你能做什么??

您可以使用类似于引用的东西,这样您就可以拥有看起来像IFigure 但实际上指向Implementation 的东西。引用可以工作,但它们不是那么动态的,所以指针也可以。

//  a pointer to base             we tell to point it to this allocated implementation
std::unique_ptr<IFigure> figure = std::make_unique<Implementation>();

当使用std::map 之类的容器时,您还可以使用这样的指针:

std::map<string,std::unique_ptr<IFigure>> figures;

每个元素的值如下所示:

+--------+---------------+
| string |    IFigure    |
+--------+---------------+

用指针:

      +------------------+
      |  Implementation  |
      +------------------+
            ^
            |
+--------+--|---+
| string | ptr  |
+--------+------+

并像这样使用它:

figures.emplace("id1", std::make_unique<Implementation>());
// or
figures["id2"] = std::make_unique<Implementation>();

// or even
void Drawing::addFigure(std::string id, std::unique_ptr<IFigure> figure) {
    // move ownership from 'figure' into 'drawings' so
    // 'drawing' becomes the owner and 'figure' becomes null.
    drawings.emplace(id, std:move(figure));
}

为什么不std::map&lt;string, IFigure*&gt;?它看起来更简单。

如果您打算让容器成为所有数据的所有者(当容器死亡时所有元素都被销毁),那么指针将变为拥有者。使用拥有原始指针会带来很多初学者难以处理的问题。如果您使用new,则可能有错误或您有非常具体的需求。

【讨论】:

    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多