为什么C++;是否允许在具有指针成员的类中编译默认复制构造函数/赋值运算符重载? 在玩C++时,我注意到,分配操作符/对象复制的标准编译器行为是一个痛苦的屁股。虽然我可以理解当类的每个成员都有一个定义的/默认的复制/赋值行为时默认代码的生成,但我不知道为什么编译器会冒着生成代码的风险,以愚蠢的方式复制指针,而没有一个警告。。。在这种情况下,为什么编译器会为用户做出决定?是否真的存在默认指针重写有意义的情况

为什么C++;是否允许在具有指针成员的类中编译默认复制构造函数/赋值运算符重载? 在玩C++时,我注意到,分配操作符/对象复制的标准编译器行为是一个痛苦的屁股。虽然我可以理解当类的每个成员都有一个定义的/默认的复制/赋值行为时默认代码的生成,但我不知道为什么编译器会冒着生成代码的风险,以愚蠢的方式复制指针,而没有一个警告。。。在这种情况下,为什么编译器会为用户做出决定?是否真的存在默认指针重写有意义的情况,c++,copy-constructor,assignment-operator,C++,Copy Constructor,Assignment Operator,@编辑: 在这件事作为火饵结束之前,我想指出我并不是故意咆哮的。正如我在评论中所说,我还想问一下,是否存在例外。普通(或哑)指针确实定义了复制和赋值行为 如果指针总是表示所有权,那么应该使用智能指针。然后,复制和分配行为更有可能(或至少可以)成为您想要的行为。仅举一个例子: 如果有一个树数据结构,其中每个节点都拥有自己的子节点,那么这些子指针将是智能指针——但是如果您想保留指向父节点的指针,那么它将是一个原始指针,因为它不管理它所指向的生命周期 我不知道为什么编译器会冒着生成复制指针的愚蠢代码的

@编辑:

在这件事作为火饵结束之前,我想指出我并不是故意咆哮的。正如我在评论中所说,我还想问一下,是否存在例外。

普通(或哑)指针确实定义了复制和赋值行为

如果指针总是表示所有权,那么应该使用智能指针。然后,复制和分配行为更有可能(或至少可以)成为您想要的行为。

仅举一个例子:
如果有一个树数据结构,其中每个节点都拥有自己的子节点,那么这些子指针将是智能指针——但是如果您想保留指向父节点的指针,那么它将是一个原始指针,因为它不管理它所指向的生命周期

我不知道为什么编译器会冒着生成复制指针的愚蠢代码的风险

将指针作为成员的类没有错,浅层复制这些类也没有错

它变得混乱的地方是资源所有权

动态内存分配是真正的罪魁祸首,没有指针成员。这只是一个单一的具体案例。其他可以包括锁、流、连接

如果所指向的内存不属于类,则没有区别。比如说,一个文件流也是一样——你可以复制这个类,并且两个副本都引用同一个流——但是你什么时候关闭这个流呢?哪个副本关闭了它?(“哪个副本删除内存?”)

有效的三原则会让你彻底地思考这些东西

总而言之——我认为在你有一个指针、流或任何其他资源的成员的任何地方都有警告是不现实的——会有很多警告,而且大多数都是无用的。

关于速度和力量

一个不幼稚的复制可能需要很长时间。如果这对你的程序来说是个问题,那么你会选择不遵守三原则是非常现实的

欢迎来到C++。你应该知道你在做什么

在这种情况下,为什么编译器会为用户做出决定

关键是编译器不会做出决定。他们让程序员决定。你到底期望什么?要制作一份深度拷贝吗?那完全不可能。考虑以下事项:

// This isn't necessarily "good" code, but it's legal
struct MyStruct
{
    void* p;
    const char* str;
};

MyStruct m1, m2;

m1.p = (void*)&m2;
m1.array = "Hello world!";
m2 = m1; // Now what do you expect to happen?

C++不会强迫您编写好的代码,因此上述内容完全合法。虽然上面的代码并不好,但它确实展示了结构中指针的一些常见用例。当将
m1
分配给
m2
时,您不能对其进行深度复制。如果深度副本是默认行为,那么这将很糟糕,因为上面的操作将无法编译。

如果所指向的对象不属于所讨论的类(一点也不少见),那么浅层副本正是您想要的。编译器无法从类定义中分辨出所有权语义是什么,因此它做出了一个合理的猜测:所有内容都是浅层复制的


如果您的类拥有一个指针的所有权语义,则您应该使用适当的智能指针(<代码> UnQuyPPTR ,<代码> SydDypTr>(代码)>等来记录所有权。

欢迎到C++。作为一个具有单个指针的类的实际例子,请参阅<代码> STD::RealthyOnWraseP< <代码>。它是一个可复制的引用,并且它被实现为指向所引用对象的单个指针。当您复制这些指针时,除了直接复制指针外,任何操作都是错误的。@GManNickG:这里的要点是该类只保存一个指针。是的,指针是有用的,但它们应该限制在库构建块中。换句话说,用户应该在他们的类中有一个
std::reference_wrapper
,瞧,零规则等等@Mehrdad:reference wrapper不花你什么钱,它为你购买了语义能力:它是自我记录的,它明确地说,“这是别人的”。C++是一种表达性语言,没有理由不让你的代码像这样明确。读过这篇文章的其他人(也许一年后你自己)就不必去查这个裸体指针的意思了。@KerrekSB:这正是一个原始指针告诉我的,我不知道你的情况。另外,我没有看到为引用包装器声明的
操作符->
。。。哪种方式违背了它的目的。