gpt4 book ai didi

c++ - 不止一种类型的对象集合

转载 作者:搜寻专家 更新时间:2023-10-31 01:53:46 24 4
gpt4 key购买 nike

是否有任何非糟糕的方法来拥有不止一种类型的对象集合?我非常高兴从一个共同的基础中派生出每种类型。我需要合理的语义,以便可以复制、分配集合等。

显然,我不能只使用基类的 vector 或列表。对象将被切片并且复制根本不起作用。使用 vector 或指针列表或智能指针是可行的,但您无法获得理智的复制语义。

要获得理智的复制语义,您需要使用类似 Boost 的 ptr_vector 的东西。但这需要一个痛苦且容易出错的基础设施。从本质上讲,您不能只从基类派生新类,因为如果它进入集合,就不会被正确复制。

这似乎是一件很常见的事情,而且我所知道的所有解决方案都非常糟糕。似乎 C++ 从根本上缺少一种方法来创建与给定实例相同的对象的新实例——即使该类型具有复制构造函数。制作cloneduplicate 函数需要在每个派生类中仔细重载。如果您在创建从基派生的新类(或从该基派生的任何其他类)时未能做到这一点——砰,您的集合就会中断。

真的没有更好的办法吗?

最佳答案

您可以使用 std::vector<boost::any>我认为可以完成大部分工作。

#include "boost/any.hpp"
#include <vector>
#include <iostream>

//Simple class so we can see what's going on
class MM {
public:
MM() { std::cout<<"Create @ "<<this<<std::endl; }
MM( const MM & o ) { std::cout<<"Copy "<<&o << " -> "<<this<<std::endl; }
~MM() { std::cout<<"Destroy @ "<<this<<std::endl; }
};

int main()
{
//Fill a vector with some stuff
std::vector<boost::any> v;
v.push_back(0);
v.push_back(0);
v.push_back(0);
v.push_back(0);

//Overwrite one entry with one of our objects.
v[0] = MM();

std::cout<<"Copying the vector"<<std::endl;
std::vector<boost::any> w;
w = v;

std::cout<<"Done"<<std::endl;
}

为此我得到了输出:

Create @ 0xbffff6ae
Copy 0xbffff6ae -> 0x100154
Destroy @ 0xbffff6ae
Copying the vector
Copy 0x100154 -> 0x100194
Done
Destroy @ 0x100194
Destroy @ 0x100154

这是我希望看到的。

编辑:

为了能够将成员视为某种常见的基本类型,您需要与 boost::any 非常相似的东西。 ,谢天谢地,这是一个相对简单的类。

template<typename BASE>
class any_with_base
{
// ... Members as for boost::any

class placeholder
{
virtual BASE * as_base() = 0;

//Other members as in boost::any::placeholder
};

template<typename ValueType>
class holder : public placeholder
{
virtual BASE * as_base() { return (BASE*)&held; }
//Other members as in boost::any::holder<T>
};

BASE* as_base() { return content?content->as_base():0; }
}

现在你应该可以这样做了:

vector< any_with_base<Base> > v;
v.push_back( DerivedA() );
v.push_back( DerivedB() );

v[0].as_base()->base_fn();
v[1].as_base()->base_fn();

any_cast<DerivedA>(v[0])->only_in_a();

我实际上不喜欢 any_cast 的语法,并会利用这个机会添加一个“as”成员函数.. 这样我就可以将最后一行写成:

v[0].as<DerivedA>()->only_in_a();

关于c++ - 不止一种类型的对象集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10663106/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com