抽象类和多态性
abstract class and polymorphism
我正在用抽象类做一些事情。
#include <iostream>
#include <vector>
using namespace std;
class Shape
{
protected:
int m_size;
public:
int getSize() { return m_size; }
virtual bool isEqual(Shape *rhs) = 0;
};
这是派生类之一:
class Circle : public Shape
{
public:
Circle(int size) { m_size = size; }
bool isEqual(Shape *rhs)
{
Circle* circle = dynamic_cast<Circle*>(rhs);
if(circle == 0)
return false; // not a Circle
return m_size == circle->getSize();
}
};
我把所有的形状都存储在一个容器中(基本上是形状指针的向量。
class Container
{
private:
vector<Shape*> v;
public:
~Container()
{
for(int i = 0; i < v.size(); i++) {
cout << "Removind element Nr. " << i << endl;
delete v[i];
}
v.erase(v.begin(), v.end());
}
bool add(Shape *shape)
{
for(int i = 0; i < v.size(); i++) {
if( v[i] == shape ) {
return false;
}
if( v[i]->isEqual(shape) ) {
return false;
}
}
v.push_back(shape);
return true;
}
};
我想知道是否可以在不将元素作为指针传递的情况下在容器中添加元素。目前它是这样工作的:
Container c;
c.add(new Circle(10));
我想以这种方式使用它:
C.add(Circle(10));
解决方案是什么?
不要按值存储多态对象。这可能会导致对象切片。
在您的情况下,甚至不可能按值存储Shape
类型的对象,因为该类具有纯虚拟方法。
如果您想要更好的资源管理,例如自动调用delete
,您可以使用shared_ptr
或unique_ptr
。
如果您想统一使用容器并将任何类型的Shape(圆形、矩形..(保存在同一容器中,则不能。例如,当前可以使用基类指针添加任何形状。但是,如果要添加对象而不是指针,则必须为每个类型声明一个容器。您将无法统一处理对象。
您需要将新对象的创建移动到Container::add
,以便仅在对象不在容器中时创建该对象。实现它的一种方法是在Shape
中声明纯虚拟Clone
函数,然后在Circle
:中定义它
virtual Shape* Clone()
{
return new Circle(*this);
}
然后,您可以按值将对象传递给add
,它将调用Clone
:
v.push_back(shape.Clone());
类似于克隆方法,您可以通过以下方式修改方法add
(在C++11中(:
template<typename T, typename...Ts>
bool Container::add(Ts&&... args)
{
std::unique_ptr<T> newShape(new T(std::forward<Ts>(args)...));
for (const Shape* shape : v) {
const auto* shapeT = dynamyc_cast<const T*>(shape);
if (shapeT != nullptr && shapeT->isEqual(newShape) ) {
return false;
}
}
v.push_back(newShape.release()); // better to have std::vector<std::unique_ptr<Shape>>...
return true;
}
然后像这样使用:
c.add<Circle>(10);
相关文章:
- 如何查找哪个类对象位于数组的特定索引上(多态性)
- C++模板方法重载和具有多态性的类访问
- 没有新成员的模板多态性派生类的大小
- 从具有多态性的类中检索数据
- 多态性抽象语法树(递归下降解析器):不可能
- 多态性:通过类文本或对象访问静态成员
- c++多态性:基类的上转换/下转换和容器,缺少数据
- C++多态性模板类:调用基类方法而不是派生类
- C++中的多态性和类抽象实例
- 多态性c++,试图访问从抽象基类派生的类的成员函数
- cout上抽象类的多态性
- 多态性:实例类
- c++中多态性基类和继承类实例化的问题
- 用于智能指针(intrusive_ptr)的抽象基类-处理继承性、多态性、可克隆性和从工厂返回的方法
- 抽象类和多态性
- 多态性基类指针
- C++抽象类和多态性
- 具有抽象类的多态性(C++)
- 抽象基类w/o多态性
- C++ 多态性 - 继承类的映射