我需要将一个对象(定义为接口)传递给方法,但我不知道该怎么做。 该方法必须将此对象添加到地图。显然,传递的对象将是接口IFigure的子对象。
void Drawing::addFigure(string id, IFigure figure) {
drawings.insert(id, figure);
}
地图的定义如下(在Drawing类中):
map<string,IFigure> drawings;
感谢您的时间!
答案 0 :(得分:1)
您不能创建抽象类的实例。
所以宣布:
IFigure figure;
这将构造一个新的IFigure
。你不能那样做。
IFigure figure = Implementation{};
这也不起作用。您正在通过复制切片的IFigure
来创建新的Implementation
。您也不能这样做。
变量是值,就像int
一样。 IFigure 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<string, IFigure*>
?看起来更简单。
如果您打算让容器成为所有数据的所有者(当容器死亡时,所有元素都将被销毁),则指针将成为所有者。使用拥有的原始指针会带来很多问题,这些问题对于初学者来说很难解决。如果您使用new
,则可能是错误或您有非常特定的需求。