使用boost::shared_ptr在一个集合中创建不同的模板类
Different templated class in a set using boost::shared_ptr
我有一些设计上的问题,我想你们中有人可能有一些线索可以帮助我。
我试着用这个简单的例子来总结我的问题:
我有两个不同的类DerivedOne
和DerivedTwo
,它们继承同一个Base
类并共享一个方法的定义。
我有一组指向client
的shared_ptr
,其中有一个对象来自两个不同的类DerivedOne
和DerivedTwo
。
因为我不想使用Base*
指针来保持这2个不同的类,我试图使客户端类模板。
但是我有两个不同的类,我不能把它们放在同一个集合里。
我认为shared_ptr
可以在不指定模板参数的情况下保存对象指针,但是我错了,或者我不知道怎么做。
我看到的另一个解决方案是将这两个不同的client
分开在两个不同的set
提前感谢您的建议。
代码如下:
#include <iostream>
#include <set>
#include <boost/shared_ptr.hpp>
class Base
{
public:
virtual void test() = 0;
};
class Derived_one
: public Base
{
public:
void test() {
std::cout << "Derived One" << std::endl;
}
};
class Derived_two
: public Base
{
public:
void test() {
std::cout << "Derived Two" << std::endl;
}
};
template <class temp_arg>
class Client
{
public:
int test(){
obj_.test();
}
protected:
temp_arg obj_;
};
typedef Client<Derived_one> ClientOne;
typedef Client<Derived_two> ClientTwo;
/// Here I don't want to specify any of the two previously declared client :
//typedef boost::shared_ptr<Client> Client_ptr;
typedef boost::shared_ptr<ClientOne> Client_ptr;
int main(int, const char**)
{
std::set<Client_ptr> Clients_;
Client_ptr client_(new ClientOne());
Clients_.insert(client_);
client_->test();
return 0;
}
如果你想看一下真实的代码:
https://github.com/gravitezero/Node/tree/experimental/src Client
对应connection
Base
类是message
两个派生类是peply
和request
。
boost共享模板指针不会执行任何没有常规指针(即将两种不同类型的指针放入同一个集合中)就无法执行的魔法。无论何时使用模板,都必须显式声明模板参数,因为模板所做的只是在编译时为您生成重复的代码。因此,当您使用模板时,编译器只是复制模板文件的次数与您使用模板参数声明的次数相同。没有模板参数,没有复制,没有模板。至少这是我的理解,我相信c++警察会纠正我,如果我错了。
因此,将两个不同类型放入同一个集合的方法是掩码放置在集合中的值。这样做的最基本的方法(也是糟糕的方法)是使您的void指针集合,然后根据上下文对插入和提取进行强制转换。这是很危险的,因为你将通过指针访问内存,而不检查指针是否指向正确的内存数量/格式(这是类型检查)。
所以真正的方法是按照pmr的建议。将集合设置为基类型指针的集合,并在从列表插入和提取时使用动态强制转换在类型之间强制转换。动态强制转换将在运行时进行检查,以确保强制转换的来源和目标类型是兼容的。如果你从Derived1转换到Base,然后再从Base转换到Derived1,这是可以的。如果您在指向相同内存的指针上从Derived1强制转换为base,然后再从base强制转换为Derived2,这将在运行时失败,因为Derived2和Derived1不兼容。
这个解释有点长,因为几个月前我也遇到了同样的设计问题,直到我看了一些资料。
为什么不使用指向Base
实例的指针呢?如果使用运行时多态性,这是唯一的方法。如果实际上不需要运行时多态性,那么使用虚成员函数是错误的。
只要使用boost::scoped_ptr
或(更好)c++ 11 std::unique_ptr
来保持base*
在Client
。
如果您选择放弃运行时多态性,您应该研究CRTP来实现静态多态性。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 从具有自定义排序的向量创建集合
- 查询数据库以在 C++ 中创建自定义类集合的最佳方法
- 创建集合向量作为类成员会在 c++ 中给出错误
- 如何创建异质对象的集合
- 创建一个抽象类类型的集合,shared_ptr的抽象类向量
- 是否可以在 C# 中创建"perfect forwarding"泛型集合?
- Boost HANA:从集合创建地图和默认值
- 如果对象尚未在集合中,则创建一个对象
- 创建集合成员(C )成员的每个置换和符号变化的集合
- 创建字符串 c++ 的常量集集合
- C++ 创建指向两个相关矢量集合中的对象的指针集合
- 如何使用(模板)迭代器值创建集合
- C++创建集合矩阵
- 使用boost::shared_ptr在一个集合中创建不同的模板类
- 如何在c++中使用我的自定义比较创建一个集合
- 创建从STL集合继承的新类带来的bug
- 如何用集合顶点列表创建boost子图
- 创建集合关联数组
- c++:如何在启动时创建类的集合