复制构造函数的问题(有点长故事......) [英] Problem with copy constructor (a bit long story...)

查看:51
本文介绍了复制构造函数的问题(有点长故事......)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,


我正在尝试实施某个班级,但我在复制版本上遇到了问题。我会尝试尽可能好地解释这一点并显示我所尝试过的
。因为它不是关于某种代码语法而是

更多''代码架构''的东西,我会使用简单的示例类

(肯定是不完整或正在工作......)只是为了说明

的想法(我可能会犯一些错误,因为我不是那么经验......)。


基本的想法是我有一个具有数据向量的类,但是该类的对象
也可以在几个

实例之间共享该数据向量: br />

A级{

vector< double * data; //指针,所以A的对象可以_share_数据。

bool data_is_shared; //这个A与另一个A共享数据吗?


A(const bool do_data_init = true); // ctor

A(const A& a); //复制构造函数

get_shared_A(); //得到一个共享''this''数据的对象A

};


Ctor:


A :: A(bool do_data_init)

{

if(do_data_init)

data = new vector< double>;

data_is_shared =!do_data_init;

}


复制ctor,总是会产生一个不共享数据的'A':


A :: A(const A& a)

{

data = new vector< double>;

data_is_shared = false;

* data = * a.data;

}


获取共享数据的对象A用''this'':


AA :: get_shared_A()

{

A a(false);


a.data = data; //只复制数据指针

返回一个;

}


问题集中在最后一个方法''get_shared_A' 。它应该返回

一个与''this'共享其数据的对象A.问题:在返回''a'',

时,复制构造函数_may_被调用,然后返回一个对象A

,它有自己的数据向量。所以这不起作用......我无法改变副本ctor因为那应该总是返回一个不会分享其数据的A(这是'对A类正确行为的要求。


在我的应用程序中,''get_shared_A''是一个运算符,它选择原始数据的一部分

''this'',返回的结果必须是一个对象A

,因为它必须像其他A'一样用在数学表达式中。


所以,使用''助手'' - 类BI试图改变这个:


AA :: get_shared_A()

{

B b;


b.data = data; //仅复制数据指针

返回b;

}


使用B类:

B级{

矢量< double *数据;

};


和额外的转换ctor for答:


A :: A(const& B b)

{

data = b.data;

data_is_shared = true;

}


所以我希望代码强制使用这个新的ctor并返回一个对象

A分享其数据。但是再次,在转换ctor之后被称为

,仍然有可能复制ctor也被调用,而且事情没有

正常工作。

事实上,我提出的所有可能的解决方案都不起作用因为你

无法确定从

''返回时是否调用了副本ctor'' get_shared_A'',这取决于你的编译器。


那么,有没有人有任何想法来克服这个问题?


Jeroen

Hi all,

I''m trying to implement a certain class but I have problems regarding
the copy ctor. I''ll try to explain this as good as possible and show
what I tried thusfar. Because it''s not about a certain code syntax but
more a ''code architecture'' thing , I''ll use simple example classes
(which are certainly not complete or working...) just to illustrate the
idea (and I may make some mistakes because I''m not that experienced...).

The basic idea is that I have a class which has a data vector, but
objects of that class can also share that data vector between several
instances:

class A {
vector<double*data; // pointer, so objects of ''A'' can _share_ data.
bool data_is_shared; // does this ''A'' share data with another A?

A(const bool do_data_init=true); // ctor
A(const A& a); // copy constructor
A get_shared_A(); // get an object A which shares ''this'' data
};

Ctor:

A::A(bool do_data_init)
{
if (do_data_init)
data = new vector<double>;
data_is_shared = !do_data_init;
}

Copy ctor, always result in an ''A'' which does not share data:

A::A(const A& a)
{
data = new vector<double>;
data_is_shared = false;
*data = *a.data;
}

Get an object A which shares data with ''this'':

A A::get_shared_A()
{
A a(false);

a.data = data; // copy the data pointer only
return a;
}

The problems focus on this last method ''get_shared_A''. It should return
an object A that shares its data with ''this''. Problem: on returning ''a'',
the copy constructor _may_ be called and then an object A is returned
which has its own data vector. So this doesn''t work... I cannot change
the copy ctor because that should always return an A which does not
share its data (that''s a requirement for correct behaviour of class A).

In my application, ''get_shared_A'' is an operator which selects a part of
the original data in ''this'', and the returned result must be an object A
because it must be used in mathematical expressions just like all other A''s.

So, using a ''helper''-class B I tried to change this in:

A A::get_shared_A()
{
B b;

b.data = data; // copy the data pointer only
return b;
}

With class B:

class B {
vector<double*data;
};

And an extra conversion ctor for A:

A::A(const& B b)
{
data = b.data;
data_is_shared = true;
}

So I wanted the code to force to use this new ctor and return an object
A which shares its data. But again, after the conversion ctor is called
it is still possible that the copy ctor is also called and things do not
work correctly.

In fact, all possible solutions I came up with do not work because you
cannot be sure if the copy ctor is called when returning from
''get_shared_A'', it depends on the compiler you have.

So, does anybody has any ideas to overcome this problem?

Jeroen

推荐答案

* Jeroen:
* Jeroen:

>

基本的想法是我有一个具有数据向量的类,但是该类的对象
也可以在几个

实例之间共享该数据向量:
>
The basic idea is that I have a class which has a data vector, but
objects of that class can also share that data vector between several
instances:



使用boost :: shared_ptr实现共享。如果你想要一个

非共享副本通过一些成员函数提供。不是通过副本

构造函数。


-

答:因为它弄乱了人们通常阅读文本的顺序。

问:为什么这么糟糕?

A:热门发布。

问:什么是最烦人的事情usenet和电子邮件?

Use boost::shared_ptr to implement the sharing. If you want a
non-shared copy provide that via some member function. Not via the copy
constructor.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Alf P. Steinbach schreef:
Alf P. Steinbach schreef:

* Jeroen:
* Jeroen:

>>
基本思想是我有一个具有数据向量的类,但该类的对象也可以共享该数据几个
实例之间的向量:
>>
The basic idea is that I have a class which has a data vector, but
objects of that class can also share that data vector between several
instances:



使用boost :: shared_ptr实现共享。如果你想要一个

非共享副本通过一些成员函数提供。不是通过副本

构造函数。


Use boost::shared_ptr to implement the sharing. If you want a
non-shared copy provide that via some member function. Not via the copy
constructor.



这可能就是问题所在。 A类所在的库使用

共享数据的概念等等。但是对于用户而言,所有这些都是不可用的,也不是可见的。用户期望类的''正常''行为

A.因此,如果库的用户使用下标运算符以便

选择一部分数据对象A并直接将其用作函数的

参数,然后调用复制构造函数,即生成非数据共享副本所需的



void user_function(A a)

{

a = 10; //参数''a''必须在这里更改,而不是原始数据!

}


void other_user_function()

{

A a;

user_function(a(1:10)); //或者我在这里使用的任何语法....

}


代码''(1:10")' '结果是A级对象与''父级'共享其

数据(这是用我原来的帖子编写的方法

''get_shared_A''在A类中,但实际上它是一个运算符),但是副本

构造函数调用''user_function''必须创建一个A,它不会在
中共享其数据为了提供正确的行为。


鉴于上述情况,我在你的建议中没有看到解决方案...


Jeroen

That may just be the problem. The library in which class A resides uses
the concept of shared data and so on. But for the user all of this is
not available, nor visible. The user expects ''normal'' behaviour of class
A. So if a user of the library uses a subscript operator in order to
select a portion of the data in an object A and directly uses that as a
parameter to a function, then the copy constructor is called which is
required to make a non data-sharing copy:

void user_function(A a)
{
a = 10; // parameter ''a'' must be changed here, not the original data!
}

void other_user_function()
{
A a;
user_function(a("1:10")); // or whatever syntax I''l use here....
}

The code ''a("1:10")'' results in an object of class A which shares its
data with its ''parent'' (this was coded in my original post by method
''get_shared_A'' in class A, but its an operator in fact), but the copy
constructor called for ''user_function'' must create an A which does not
share its data in order to provide correct behaviour.

Given the above, I don''t see the solution in your suggestion...

Jeroen


* Jeroen:
* Jeroen:

Alf P. Steinbach schreef:
Alf P. Steinbach schreef:

> * Jeroen:
>* Jeroen:

>>>
基本的想法是我有一个有数据向量的类,但该类的对象也可以在s之间共享该数据向量几个
实例:
>>>
The basic idea is that I have a class which has a data vector, but
objects of that class can also share that data vector between several
instances:


使用boost :: shared_ptr实现共享。如果你想通过一些成员函数提供
非共享副本。不是通过
复制构造函数。


Use boost::shared_ptr to implement the sharing. If you want a
non-shared copy provide that via some member function. Not via the
copy constructor.



这可能就是问题所在。 A类所在的库使用

共享数据的概念等等。但是对于用户而言,所有这些都是不可用的,也不是可见的。用户期望类的''正常''行为

A.因此,如果库的用户使用下标运算符以便

选择一部分数据对象A并直接将其用作函数的

参数,然后调用复制构造函数,即生成非数据共享副本所需的



void user_function(A a)

{

a = 10; //参数''a''必须在这里更改,而不是原始数据!

}


void other_user_function()

{

A a;

user_function(a(1:10)); //或者我在这里使用的任何语法....

}


代码''(1:10")' '结果是A级对象与''父级'共享其

数据(这是用我原来的帖子编写的方法

''get_shared_A''在A类中,但实际上它是一个运算符),但是副本

构造函数调用''user_function''必须创建一个A,它不会在
中共享其数据为了提供正确的行为。


鉴于上述情况,我在你的建议中没有看到解决方案......


That may just be the problem. The library in which class A resides uses
the concept of shared data and so on. But for the user all of this is
not available, nor visible. The user expects ''normal'' behaviour of class
A. So if a user of the library uses a subscript operator in order to
select a portion of the data in an object A and directly uses that as a
parameter to a function, then the copy constructor is called which is
required to make a non data-sharing copy:

void user_function(A a)
{
a = 10; // parameter ''a'' must be changed here, not the original data!
}

void other_user_function()
{
A a;
user_function(a("1:10")); // or whatever syntax I''l use here....
}

The code ''a("1:10")'' results in an object of class A which shares its
data with its ''parent'' (this was coded in my original post by method
''get_shared_A'' in class A, but its an operator in fact), but the copy
constructor called for ''user_function'' must create an A which does not
share its data in order to provide correct behaviour.

Given the above, I don''t see the solution in your suggestion...



不要对它说好话,你很困惑。你想要一个具有两个不兼容属性的副本

构造函数:制作一个非共享的

副本(仅限),并制作一个共享副本(仅限)。如果你在上面写的那个共享是一个实现细节,那么试着准确地定义

它的意图是什么;例如可能是你想要实现的是b
实现的是一些写时复制方案,在这种情况下就像我写的一样。


- -

答:因为它弄乱了人们通常阅读文字的顺序。

问:为什么这么糟糕?

答:热门发布。

问:usenet和电子邮件中最烦人的是什么?

Not to put to fine words on it, you''re confused. You want a copy
constructor that has two incompatible properties: making a non-shared
copy (only), and making a shared copy (only). If the sharing, as you
write above, is an implementation detail, then try to define exactly
what it''s meant to accomplish; e.g. it may be that what you''re trying to
achieve is some copy-on-write scheme, in which case do as I wrote.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


这篇关于复制构造函数的问题(有点长故事......)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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