我有一些设计问题,我想你们中的某个人可能会提供一些线索来帮助我。
我试着用这个简单的例子来总结我的问题:
我有两个不同的类 DerivedOne
和 DerivedTwo
继承自同一个 Base
类并共享一个方法的定义。
我有一组指向 client
的 shared_ptr
,其中有一个对象来自两个不同的类 DerivedOne
和 DerivedTwo
。
因为我不想使用 Base*
指针来保存这两个不同的类,所以我尝试制作客户端类模板。
但是我有两个不同的类(class),我不能把他们放在同一个类(class)里。
我以为 shared_ptr
可以在不指定模板参数的情况下保存对象指针,但我错了,或者我不知道该怎么做。
我看到的另一个解决方案是将这 2 个不同的 client
分成 2 个不同的 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++ 警察会纠正我。
所以把两个不同的类型放到同一个集合中的方法就是屏蔽放置在集合中的值。执行此操作的最基本方法(也是不好的方法)是制作空指针的集合,然后根据上下文进行插入和提取。这是危险的,因为这样您将通过指针访问内存,而无需检查指针是否指向正确的内存量/格式(这是类型检查)。
所以真正的方法是按照 pmr 的建议去做。使您的集合成为基类型指针的集合,并在从列表中插入和提取时使用动态转换在类型之间进行转换。动态转换将在运行时进行检查,以确保您要转换的类型是兼容的。 IE 如果你从 Derived1 转换到 Base,然后再从 Base 转换到 Derived1,这是可以的。如果您从 Derived1 转换为 base,然后在指向同一内存的指针上从 base 转换为 Derived2,这将在运行时失败,因为 Derived2 和 Derived1 不兼容。
这个解释有点长,因为几个月前我遇到了同样的设计问题,直到我做了一些阅读。
关于c++ - 使用 boost::shared_ptr 的集合中的不同模板类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7650931/