返回派生类,而不是基类
Returning the derived instead of the base class
我正在创建一个"basket"(容器)来存储从另一个类派生的"items"(类)。其思想是方法select
返回正确的类(派生的),而不是基。
#include <iostream>
#include <map>
#include <typeinfo>
class Item;
class Pencil;
class Basket
{
public:
Basket();
void insert(int id, Item item);
Item select(int id);
private:
std::map<int, Item> basket;
};
class Item
{
};
class Pencil : public Item
{
public:
Pencil() {}
void draw() { std::cout << "stackoverflow" << std::endl; }
};
Basket::Basket() {}
void Basket::insert(int id, Item item)
{
basket.insert(std::pair<int, Item>(id, item));
}
Item Basket::select(int id)
{
return basket[id];
}
int main(int argc, char ** argv)
{
Basket basket;
Pencil pencil;
basket.insert(1, pencil);
auto redpen = basket.select(1);
std::cout << typeid(redpen).name() << std::endl;
return 0;
}
实时预览
输出:4项(预计为6项)
通过这种方式,我不能使用方法draw
,因为这不是我添加到篮(容器)上的项(类),它已转换为基类。
有没有一种方法可以返回正确的类,我的意思是,派生的类,但保持这种结构?
谢谢。
您在问题评论中请求的示例:
#include <iostream>
#include <map>
#include <memory>
#include <typeinfo>
class Item;
class Pencil;
class Basket
{
public:
Basket();
void insert( int id, std::shared_ptr<Item> item );
auto select( int id ) -> std::shared_ptr<Item>;
private:
std::map< int, std::shared_ptr<Item> > basket;
};
class Item
{
public:
virtual ~Item() {}
};
class Pencil
: public Item
{
public:
Pencil() {}
void draw() { std::cout << "stackoverflow" << std::endl; }
};
Basket::Basket() {}
void Basket::insert( int const id, std::shared_ptr<Item> const item )
{ basket[id] = item; }
auto Basket::select( int const id )
-> std::shared_ptr<Item>
{ return basket[id]; }
int main()
{
Basket basket;
basket.insert(1, std::make_shared<Pencil>() );
auto redpen = basket.select( 1 );
std::cout << typeid(*redpen).name() << std::endl;
}
不能按值返回派生类,因为这样会得到切片,这意味着复制派生类,就好像它只是一个基一样,留下所有添加的内容(包括任何应该是派生类的提示)。
相反,返回一个指向新分配的派生的指针作为基*。不过别忘了清理一下
为了捕捉删除失败,您可以查看智能指针,也可以共享缓存的返回值
当返回的值实际存在的时间与需要的时间一样长时,您也可以返回const& base
。
您希望将C++多态性与RTTI(运行时类型标识)一起使用。一种解决方案是使用指针,因此具有:
class Basket
{
public:
Basket();
void insert(int id, Item *item);
Item *select(int id);
private:
std::map<int, Item*> basket;
};
这将需要一些动态分配(新操作),并且您可以使用C++11通过使用内存头的std::shared_ptr来消除删除操作。
相关文章:
- 指向基类派生类的 std::unique_ptr 的指针
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 从模板基类派生是否在派生类声明的点实例化模板
- 使从一个基类派生的类能够使用继承的受保护成员
- C++多态性访问基类派生类字段
- C++派生类的设置属性到从同一基类派生的未知类对象
- 使用void* 参数定义纯虚函数的抽象基类.派生类匹配参数是指向某种类型的指针
- 在C++中,如何使用将保存从基类派生的任何对象的类成员
- 如何测试从依赖于外部系统的外部基类派生的类
- 如何从模板基类派生非模板类
- 在派生类中使用声明并不能隐藏从基类派生的相同函数
- 从具有静态结构的基类派生
- 具有从 c++ 中的非模板基类派生的模板类的事件系统
- C++ 调用从基类派生的覆盖函数
- 不清楚如何在从抽象基类派生的类中实现运算符重载
- 如何正向声明从正向声明的模板基类派生的类
- 是否可以从 std::enable_shared_from_this 和抽象基类派生
- 多态性c++,试图访问从抽象基类派生的类的成员函数
- C++多重继承,基类派生自同一类
- 基类派生类访问-如何