c ++将对象存储到对象的构造函数中的对象数组中 [英] c++ storing an object into an array of objects within the constructor of that object

查看:90
本文介绍了c ++将对象存储到对象的构造函数中的对象数组中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个对象,每当我创建一个对象,然后将该对象存储在一个静态类变量中,该变量是所有创建的对象的数组。



我是c ++的新手,不知道如何完成这个。



以此为例:

  class Rectangle 
{
private:
int width;
int length;
//创建一个Rectangle对象数组的代码
//保存所有创建的Rectangles

public:
Rectangle();
Rectangle(int x,int y);
};

Rectangle :: Rectangle()
{
width = 0;
length = 0;
//将此对象的实例添加到Rectangle对象数组的代码
}

Rectangle :: Rectangle(int x,int y)
{
width = x;
length = y;
//将此对象的实例添加到Rectangle对象数组的代码
}

这是可能的吗?

解决方案

现在我们倾向于避免普通的数组和正常的指针。
$ b

所以去智能指针和STL容器。
由于你的对象将活着和死亡,一个向量可能不会很快稀疏,有很多对应于你不再使用的(删除)对象的洞。



另一个解决方案是无序映射(散列表)。然后我们需要一个键。我们不会考虑将a(this)指针的值转换为int或long,因为这是一个非常危险的方式。



因此,我们必须支付一些唯一ID(请参阅boost uuid)。这对于计算时间也是昂贵的,但是所有这种机制将节省时间(用于编写代码文档)。



然后我们需要一个智能指针。
当你想跟踪所有创建的对象,我们将去一个强制的工厂函数来创建你的对象。因为它们可能不是唯一拥有的,所以工厂函数的唯一选择是拒绝共享指针。



这不是直接的共享指针,可以存储在我们的容器,因为它会阻止我们容易地摆脱对象一旦不再需要(容器内的共享指针仍然会参与对象计数)。



共享指针可能会得到一个自定义删除器,让我们为容器做一些内务处理



这是一个弱指针(不参与对象计数(或在一些非常



这里是一些代码(原谅我我选择了小部件而不是矩形):



我们的类必须继承这个好奇的类(例如见Scott Meyers的新书Effective Modern C ++第19项)

 code> class widget:public std :: enable_shared_from_this< widget> 

别名(〜typedef)

 使用widget_weakptr_cont_t = std :: unordered_map< std :: string,std :: weak_ptr< widget>> 
使用widget_smrtp_t = std :: shared_ptr< widget> ;;
using uuid_t = boost :: uuids :: uuid;

工厂功能

  static widget_smrtp_t widget_factory(void); 

容器

  static widget_weakptr_cont_t widget_cont; 

构造函数是私有的(你也可以阻止所有其他形式的复制或移动构造规则)

  private:
widget
void self_emplace(void);
const uuid_t uuid_tag;

共享指针的自定义删除程序

  auto widgetDeleter = [](widget * pw){
std :: cout< 小部件删除器< std :: endl;

widget :: widget_cont.erase(pw-> uuid_to_string());

delete pw;

if(widget :: widget_cont.empty())
std :: cout<< No Widget left<< std :: endl; };

工厂功能

  widget :: widget_smrtp_t widget :: widget_factory(void)
{
auto wshp = widget_smrtp_t(new widget(),widgetDeleter);

wshp-> self_emplace();

return wshp;

}

self_emplace函数

  void widget :: self_emplace(void)
{
widget :: widget_cont.emplace(uuid_to_string(),shared_from_this());
}

然后你可以在其他一些函数)

  auto pw = widget :: widget_factory 

从容器中检索我们的对象的示例可以是

  for(auto const& it:widget :: widget_cont)
{
//如果通过uuid感兴趣我们通常做
/ / std :: cout<< it.first<< std :: endl;
//对于exercice,我们执行以下操作:
auto shp = it.second.lock();
if(shp)
{
std :: cout< shp-> uuid_to_string()<< std :: endl;
}

}

(不显示这里的post已经太长)
只做一个全局因子共享指针(我们的一个小部件)的副本。
容器不会被func中的内容修改。



func2创建另一个本地小部件,在离开func2时被销毁。



最后,全局构造的窗口部件只在结尾处被销毁。

 你好世界! 
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0

func
Widget elems are:
84871b52-0757-44c1-be23- fb83e69468c0

func2
小部件元素是:
b2aedb78-8bb0-427e-9ada-fce37384f7de
84871b52-0757-44c1-be23-fb83e69468c0

Widget deleter
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0

bye!
小部件删除程序
无小部件剩余

我希望所有这些可以帮助



NGI



EDIT 2016.08.21
我发布了unabridged代码 Coliru上的代码
这不会更清楚,因为当我第一次回答我尝试其他语法功能只是为了测试。



无论如何,你现在都在手中(有时我不公布一个完整的代码,以避免复制/粘贴问题)



最近我试图简化我的代码,但没有成功,2个想法:




I am trying to create an object and everytime I create an object, I then store that object in a static class variable that is an array of all of the objects created.

I am new to c++ and have no idea how to accomplish this. I have done it in Java before, but I am stuck here.

Take this for example purposes:

class Rectangle
{
    private:
        int width;
        int length;
        // Code to create an array of Rectangle Objects 
        // that hold all the the Rectangles ever created

    public:
        Rectangle();
        Rectangle(int x, int y);
};

Rectangle::Rectangle()
{
    width = 0;
    length = 0;
    // code to add an instance of this object to an array of Rectangle Objects
}

Rectangle::Rectangle(int x, int y)
{
    width = x;
    length = y;
    // code to add an instance of this object to an array of Rectangle Objects
}

Is this possible?

解决方案

Nowadays we tend to avoid plain array and normal pointers.

So go for smart pointers and STL containers. As your objects will live and die, a vector may not be soon sparse, having lots of holes corresponding to the (deleted) objects you do not use anymore.

Another solution would be an unordered map (hash table). We then need a key. We will not think about transforming the value of a (the this) pointer to a int or long as it is a very dangerous way to go.

So we must pay for some unique id ( see boost uuid ). This is also costly for the computing time but all this mechanism will save you time ( for writing code documentation ).

We then need a smart pointer. As you want to keep track of all the object created we will go for a mandatory "factory" function to create your objects. As they may not be uniquely owned the only choice left for the factory function is to reject a shared pointer.

This is not directly a shared pointer that may be stored inside our container as it would prevent us to easily get rid of the object once not needed anymore ( the shared pointer inside the container would still participate to the object count ).

Shared pointer may get a custom deleter that will let us do some housekeeping for the container

So this is a weak pointer ( that do not participate to the object count ( or in some very small extent( weak count ) ) that is chosen for our container.

Here is some code ( forgive me I chose widget and not rectangle ):

Our class that must inherit from this curious class ( e.g see Scott Meyers new book Effective Modern C++ item 19 )

class widget:public std::enable_shared_from_this<widget>

alias ( ~ typedef )

using widget_weakptr_cont_t  = std::unordered_map<std::string,std::weak_ptr<widget>>;
using widget_smrtp_t       = std::shared_ptr<widget>;
using uuid_t               = boost::uuids::uuid;

The factory function

static widget_smrtp_t widget_factory(void);

The container

static widget_weakptr_cont_t widget_cont;

The constructor is private ( you may also prevent all the other form of copy or move construction to strengthen the rule )

private:
    widget();
    void self_emplace(void);
    const uuid_t uuid_tag;

The custom deleter for the shared pointers

auto widgetDeleter = [](widget* pw) {
std::cout << "Widget deleter" << std::endl;

widget::widget_cont.erase(pw->uuid_to_string());

delete pw;

if ( widget::widget_cont.empty() )
    std::cout << "No Widget left" << std::endl; };

The factory function

widget::widget_smrtp_t widget::widget_factory(void)
{
    auto wshp = widget_smrtp_t(new widget(),widgetDeleter);

    wshp->self_emplace();

    return wshp;

}

The self_emplace function

void widget::self_emplace(void)
{
    widget::widget_cont.emplace(uuid_to_string(),shared_from_this());
}

You may then use your factory function inside some other functions ( or main( ) )

auto pw = widget::widget_factory();

An example for retrieving our object from the container could be

for ( auto const & it : widget::widget_cont )
{
   //if interested by uuid we normally do
   // std::cout << it.first << std::endl;
   //For exercice we do the following:
   auto shp = it.second.lock();
   if ( shp )
   {
       std::cout << shp->uuid_to_string() << std::endl;
   }

}

In the execution below the function func ( not displayed here the post is already too long ) only makes a copy of a globally factored shared pointer (to one of our widget). The container is not modified by what happened inside func.

func2 creates another local widget that is destroyed when leaving func2. container is shown at these 2 steps.

Finally the globally constructed widget is only destroyed at the end (of the main )

Hello world!
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0

func
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0

func2
Widget elems are:
b2aedb78-8bb0-427e-9ada-fce37384f7de
84871b52-0757-44c1-be23-fb83e69468c0

Widget deleter
Widget elems are:
84871b52-0757-44c1-be23-fb83e69468c0

bye !
Widget deleter
No Widget left

I hope all of this may help

NGI

EDIT 2016.08.21 I publish the "unabridged code" Code on Coliru It will not be much clearer because when I first replied I tried also other syntax features just for test.

Anyway you have now all in hands ( sometimes I do not publish a full code in order to avoid the "homework" copy/paste problem )

Lately I tried to simplify my code without success, 2 thoughts:

这篇关于c ++将对象存储到对象的构造函数中的对象数组中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆