复制构造函数存在问题(说来话长了一点…)[英] Problem with copy constructor (a bit long story...)

问题描述

大家好,

我正在尝试实现某个类,但我遇到了关于
的问题复制ctor.我会尽量解释清楚并展示
到目前为止我尝试了什么.因为它不是关于特定的代码语法,而是
更多的是"代码架构"的东西,我将使用简单的示例类
(当然不完整或不工作......)只是为了说明
想法(我可能会犯一些错误,因为我没有那么有经验......).

基本思想是我有一个有数据向量的类,但是
该类的对象也可以在多个
之间共享该数据向量实例:

A类{
向量<双*数据;//指针,所以''A''的对象可以_share_数据.
bool data_is_shared;//这个 ''A'' 是否与另一个 A 共享数据?

A(const bool do_data_init=true);//演员
A(常量A&a);//复制构造函数
一个 get_shared_A();//获取一个对象 A,它共享 ''this'' 数据
};

导演:

A::A(bool do_data_init)
{
如果(do_data_init)
数据 = 新向量<双>;
data_is_shared = !do_data_init;
}

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

A::A(const A& a)
{
数据 = 新向量<双>;
data_is_shared = false;
*data = *a.data;
}

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

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

a.数据=数据;//只复制数据指针
返回一个;
}

问题集中在最后一个方法"get_shared_A"上.它应该返回
与"this"共享数据的对象 A.问题:返回"a"时,
复制构造函数_可以_被调用,然后返回一个对象 A
它有自己的数据向量.所以这不起作用......我无法改变
复制ctor,因为它应该总是返回一个不
共享其数据(这是 A 类正确行为的要求).

在我的应用程序中,''get_shared_A'' 是一个运算符,它选择
''this''中的原始数据,返回结果必须是对象A
因为它必须像所有其他 A's 一样用于数学表达式.

所以,使用''helper''-class B 我试图改变它:

A A::get_shared_A()
{
B b;

b.数据=数据;//只复制数据指针
返回 b;
}

B类:

B类{
向量};

还有一个 A 的额外转换 ctor:

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

所以我希望代码强制使用这个新的ctor并返回一个对象
A 共享其数据.但同样,在调用转换 ctor 之后
仍然有可能复制 ctor 也被调用而事情没有
正常工作.

事实上,我想出的所有可能的解决方案都行不通,因为你
无法确定从
返回时是否调用了复制ctor''get_shared_A'',这取决于你的编译器.

那么,有没有人有办法解决这个问题呢?

Jeroen

推荐答案

* Jeroen:
>
基本思想是我有一个有数据向量的类,但是
该类的对象也可以在多个
之间共享该数据向量实例:
使用 boost::shared_ptr 来实现共享.如果你想要一个
非共享副本通过一些成员函数提供.不是通过副本


--
A:因为它打乱了人们正常阅读文本的顺序.
问:为什么会这么糟糕?
A:顶帖.
问:usenet 和电子邮件中最烦人的事情是什么?

Alf P. Steinbach schreef:
*杰伦:
>>
基本思想是我有一个具有数据向量的类,但是
该类的对象也可以在多个
实例之间共享该数据向量:

使用 boost::shared_ptr 来实现共享.如果你想要一个
非共享副本通过一些成员函数提供.不是通过副本
构造函数.
这可能就是问题所在.A类所在的库使用
共享数据的概念等等.但是对于用户来说,这一切都是
不可用,也不可见.用户期望类的"正常"行为
A. 所以如果库的用户使用下标运算符来
选择对象A中的一部分数据并直接将其用作
函数的参数,然后调用复制构造函数,即
制作非数据共享副本所需:

void user_function(A a)
{
a = 10;//这里必须改参数''a'',而不是原来的数据!
}

void other_user_function()
{
一个;
user_function(a("1:10"));//或者我在这里使用的任何语法....
}

代码 ''a("1:10")'' 导致 A 类的对象共享它的
带有"父级"的数据(这是在我的原始帖子中通过方法编码的
A类中的''get_shared_A'',但实际上它是一个运算符),但是副本
为''user_function''调用的构造函数必须创建一个不
共享其数据以提供正确的行为.

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

杰罗恩

*杰罗恩:
Alf P. Steinbach schreef:
>* 杰伦:
>>>
基本思想是我有一个具有数据向量的类,但是
该类的对象也可以在多个
实例之间共享该数据向量:

使用 boost::shared_ptr 实现共享.如果您想要一个
非共享副本,请通过一些成员函数提供.不是通过
复制构造函数.

这可能就是问题所在.A类所在的库使用
共享数据的概念等等.但是对于用户来说,这一切都是
不可用,也不可见.用户期望类的"正常"行为
A. 所以如果库的用户使用下标运算符来
选择对象A中的一部分数据并直接将其用作
函数的参数,然后调用复制构造函数,即
制作非数据共享副本所需:

void user_function(A a)
{
a = 10;//这里必须改参数''a'',而不是原来的数据!
}

void other_user_function()
{
一个;
user_function(a("1:10"));//或者我在这里使用的任何语法....
}

代码 ''a("1:10")'' 导致 A 类的对象共享它的
带有"父级"的数据(这是在我的原始帖子中通过方法编码的
A类中的''get_shared_A'',但实际上它是一个运算符),但是副本
为''user_function''调用的构造函数必须创建一个不
共享其数据以提供正确的行为.

鉴于上述情况,我在您的建议中看不到解决方案...
更不用说它了,你很困惑.你想要一个副本
具有两个不兼容属性的构造函数:制作非共享
复制(仅),并制作共享副本(仅).如果分享,就当你
写在上面,是一个实现细节,然后尝试准确定义
它的目的是什么;例如这可能就是你想要的
实现是一些写时复制方案,在这种情况下按照我写的那样做.

--
A:因为它打乱了人们正常阅读文本的顺序.
问:为什么会这么糟糕?
A:顶帖.
问:usenet 和电子邮件中最烦人的事情是什么?

本文地址:https://www.itbaoku.cn/post/1050556.html