早上好,下午或晚上,
当将一个给定的类实现为一个不可变的类,没有任何方法或属性以任何方式暴露私有/内部字段时,很容易复制一个不好的做法,或者它可以毫无问题地完成,因为它可能需要更少的对象来实例化?
非常感谢你.
我基本上寻找一个通用函数副本(数组),它将返回相同的n维数组,而不会引用前一个数组.
>>> a = [1,2,3]
>>> b = a[:]
>>> id(a[0]) == id(b[0])
True
>>> b[0] = 99
>>> id(a[0]) == id(b[0])
False
Run Code Online (Sandbox Code Playgroud)
我理解,为了制作浅色副本,我们可以使用切片,还有一个复制模块.但是为什么写入"b"索引会改变id.
我想问一下,我们将如何实现一个类的复制构造函数,该类具有自身指针作为其数据成员,我想实现深层复制,
class City
{
string name;
City* parent;
public:
City(string nam, double dcov);
City(string nam, double dcov, City* c);
City(const City& obj)
{
this-> name = obj.name;
// how to assign parent
parent = new City(??)
}
~City();
void setName(string name1);
void setDistanceCovered(int dist);
string getName();
double getDistanceCovered();
City* getParent(){return parent;}
};
Run Code Online (Sandbox Code Playgroud)
我很困惑,这行// how to assign parent
parent = new City(??)会再次调用构造函数而不是深层复制?问候.
注意我问这是一个std::string特定的问题,而不是一般如何传递一个对象.
我会删除这个问题,但由于它的答案,我不被允许.我相信答案可能倾向于堕落,以回答更常见的问题:"用C++传递对象的最佳方法是什么?" 关于堆栈溢出的这些更一般的答案有许多重复,即使这个精确的问题本身可能不是重复.这种退化可能是因为问题是一个不合适的问题,而且std :: string类没有什么特别之处.这个问题并没有高度投票,这表明它并不有趣.在那种情况下我很糟糕.也许一个mod会看到这个黑色的文字,怜悯我并杀死这个问题.
以下哪个签名表示将非const std::string实例传递给不修改它的函数的最快方法,考虑到调用站点上调用的总体开销,包括底层字符数组的深层副本是否会在通话之前产生?
extern void eat_string_by_value (std::string s);
extern void eat_const_string_by_value (const std::string s);
extern void eat_string_by_reference (std::string& s);
extern void eat_const_string_by_reference(const std::string& s);
Run Code Online (Sandbox Code Playgroud)
注意我问这是一个std::string特定的问题,而不是一般如何传递一个对象.特别是,我的问题是由以下因素刺激:
我没有看到我的问题是前一个问题的副本,它本身标记为一个普通对象的副本,传递一个< 传递参数为std :: string或const std :: string&?>因为这些特定类型的详细点.
关于相关问题的一个有趣答案:
以下是示例代码:
from copy import deepcopy
List = [range(3), range(3), range(3)]
a = deepcopy(List)
b = [each[:] for each in List]
Run Code Online (Sandbox Code Playgroud)
我知道初始化a所需的时间比b的时间要慢,但为什么会这样呢?深度复制和[列表中的每个[:]之间有什么区别?为什么deepcopy这么慢?
有没有办法为类编写一个拷贝构造函数(比如说Copyable,它可以保存std::unique_ptr一个Base类(但实际上是存储Derived对象).
快速测试显示预期的切片发生,因为Copyable不知道它所持有的实际类型.所以我想一个clone方法是必要的,但我想知道是否有办法让编译器以更好的方式处理它?
切片代码:
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data = std::make_unique<Base>(*other.data);
}
std::unique_ptr<Base> data; …Run Code Online (Sandbox Code Playgroud) smart-pointers deep-copy copy-constructor move-semantics c++11
在python3.5中使用append方法时会出现一些问题。代码显示
# generate boson basis in lexicographic order
def boson_basis(L,N):
basis=[]
state=[0 for i in range(1,L+1)]
pos=0
# initialize the state to |N,0,...,0>
state[0]=N
basis.append(state)
# find the first non-zero position in reverse order
while state[L-1]<N:
for i in range(-2,-L-1,-1):
if state[i]>0:
pos=L+i
break
sum=0
for i in range(0,pos):
sum=sum+state[i]
state[pos]=state[pos]-1
state[pos+1]=N-sum-state[pos]
basis.append(state)
return basis
result=boson_basis(3,3)
Run Code Online (Sandbox Code Playgroud)
预期结果应该是[[3,0,0],[2,1,0],...,[0,0,3]],但是此代码会产生错误的结果,并且所有元素都与最后一个元素相同,即[[0,0,3],...,[0,0,3]]。我使用pdb对其进行调试,我发现一旦state修改了,state附加到其中的前者basis也会同时更改。它意味着自动append使用deepcopy,这超出了我的理解。实际上,如果我们basis(state.copy())显式使用,则可以修复此错误。
另一方面,以下简单代码显示使用中没有错误 append
x=3
b=[]
b.append(x)
x=x+2
Run Code Online (Sandbox Code Playgroud)
后 …
我正在尝试初始化表示 3x3 数组的列表列表:
import copy
m = copy.deepcopy(3*[3*[0]])
print(m)
m[1][2] = 100
print(m)
Run Code Online (Sandbox Code Playgroud)
输出是:
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[0, 0, 100], [0, 0, 100], [0, 0, 100]]
Run Code Online (Sandbox Code Playgroud)
这不是我所期望的,因为每行的最后一个元素是共享的!我确实通过使用得到了我需要的结果:
m = [ copy.deepcopy(3*[0]) for i in range(3) ]
Run Code Online (Sandbox Code Playgroud)
但我不明白为什么第一个(和更简单的)形式不起作用。不是deepcopy应该很深吗?
默认的拷贝构造函数在C++中是执行浅拷贝还是深拷贝?
我真的很困惑cpp中的默认复制构造函数,因为它执行浅拷贝或深拷贝,就像我v2=v1;想的那样v1={1,2,3},现在如果我已经完成v2[0]=1;它没有得到反映但我听说它是浅拷贝,有人可以解释一下吗?
deep-copy ×10
python ×4
c++ ×3
c++11 ×3
shallow-copy ×3
copy ×2
python-3.x ×2
arrays ×1
c# ×1
c++98 ×1
immutability ×1
javascript ×1
list ×1
stdstring ×1
this-pointer ×1