与不带dynamic_pointer_cast的智能指针组合
Composite with smart pointers without dynamic_pointer_cast
我使用智能指针实现了复合模式,它一直工作到某个点。
问题是,我只能使用在接口中实现的方法,我不能使用在派生类中定义的方法,而不使用dynamic_pointer_cast
,我不想要它。
我想知道不使用dynamic_pointer_cast
是否有可能做到这一点。
我听说我需要实现访问者模式,但我真的不知道如何实现,也不知道它是否适合这个问题。
#include <iostream>
#include <vector>
#include <memory>
class Fruit
{
public:
virtual void getOld() = 0;
};
class Orange : Fruit
{
public:
Orange() {}
void add(std::shared_ptr<Fruit> f)
{
v.push_back(f);
}
std::shared_ptr<Fruit> get(int k)
{
return v[k];
}
void getOld()
{
std::cout << "Orange - I'm old." << std::endl;
}
private:
std::vector<std::shared_ptr<Fruit>> v;
};
class Bitter : public Fruit
{
public:
Bitter() {}
void getOld()
{
std::cout << "Bitter - I'm old." << std::endl;
}
void getNew()
{
std::cout << "Bitter - I'm new." << std::endl;
}
};
int main(int argc, char ** argv)
{
auto orange = new Orange;
orange->add(std::make_shared<Bitter>());
auto bitter = orange->get(0);
bitter->getOld();
return 0;
}
就像你在实时预览中看到的那样,它可以工作,但是当我尝试使用:
int main(int argc, char ** argv)
{
auto orange = new Orange;
orange->add(std::make_shared<Bitter>());
auto bitter = orange->get(0);
bitter->getOld();
bitter->getNew();
return 0;
}
I got errors:
错误:'class Fruit'没有名为'getNew'的成员
我认为这里的问题是,它将与多态性工作,但方法'getNew'不存在于母类,所以你需要定义它并使其虚拟。这是不使用对象强制转换的唯一方法。这条线应该行得通。
virtual void getNew() = 0;
一个可能的解决方案是在Orange
中添加以下功能。
template <typename T>
T* get(int k)
{
return dynamic_cast<T*>(v[k].get());
}
然后使用:
auto bitter = orange->get<Bitter>(0);
bitter->getOld();
bitter->getNew();
执行dynamic_cast
,但被定位为Orange
。
关于"复合图案"的信息可以从GOF书中找到。当然,它已经在图形类的基础上进行了解释。
键 复合模式是一个抽象类, 是两个原语和他们的容器。对于图形系统,这个类是Graphic。Graphic声明了像Draw这样特定于图形对象的操作。它还声明了所有复合对象共享的操作,例如访问和管理其子对象的操作。
根据以上解释,在使用复合模式时,我们应该理想地声明节点的叶子和非叶子(容器)类型的所有可能的接口。我认为这是必要的,以便让客户统一地处理单个对象和对象的组合。因此,理想情况下,在使用这种特定模式时,应该按照以下方式声明类。任何基于客户端代码中对象的确切类型编写的逻辑都违反了该模式的本质。
//Abstract class which should have all the interface common to
// Composite and Leaf class. It may also provide the default
// implementation wherever appropriate.
class Fruit {
public:
virtual void getOld() = 0;
virtual void getNew() = 0;
virtual void add(std::shared_ptr<Fruit> f) { }
virtual std::shared_ptr<Fruit> get(int index ) {return nullptr; }
virtual ~Fruit() { }
};
//Composite Node
class Orange : Fruit {
public:
Orange() {}
void add(std::shared_ptr<Fruit> f) { v.push_back(f); }
std::shared_ptr<Fruit> get(int k) { return v[k]; }
void getOld() { std::cout << "Orange - I'm old." << std::endl; }
void getNew() { std::cout << "Orange - I'm new." << std::endl; }
private:
std::vector<std::shared_ptr<Fruit>> v;
};
//Leaf node
class Bitter : public Fruit {
public:
Bitter() {}
void getOld() { std::cout << "Bitter - I'm old." << std::endl; }
void getNew() { std::cout << "Bitter - I'm new." << std::endl; }
};
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 优先顺序:智能指针和类析构函数
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 智能指针作为无序映射键,并通过引用进行比较
- 智能指针概念所有权和寿命
- 正在理解智能指针,但出现错误:未分配正在释放的指针
- 尝试使用智能指针时引发异常
- 我可以制作指向智能指针的智能指针吗?
- 通过智能指针和转换对基本模板参数进行模板推导
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 从堆栈分配的原始指针构造智能指针
- 初始化指向类实例的智能指针并访问其方法
- 如何使用 std::make_shared 创建基类类型的智能指针?
- 给定一个指向堆分配内存的指针,智能指针实现如何为其找到合适的释放函数?
- 编译器不会使用 -std=c++11 编译智能指针
- 具有智能指针的多态性
- C++:矢量分配器行为、内存分配和智能指针
- 在什么情况下,需要共享智能指针而无法使用唯一指针?
- 指向函数签名中的常量智能指针
- 使用智能指针附加的继承对象的深层复制