标签: default-copy-constructor

包含其他对象的类的C++隐式复制构造函数

我知道如果你没有自己实现,编译器有时会提供一个默认的复制构造函数.我很困惑这个构造函数到底是做什么的.如果我有一个包含其他对象的类,其中没有一个具有声明的复制构造函数,那么行为是什么?例如,像这样的类:

class Foo {
  Bar bar;
};

class Bar {
  int i;
  Baz baz;
};

class Baz {
  int j;
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我这样做:

Foo f1;
Foo f2(f1);
Run Code Online (Sandbox Code Playgroud)

默认的复制构造函数会做什么?将编译器生成的复制构造函数Foo调用编译器生成的构造函数Bar进行复制bar,然后调用编译器生成的复制构造函数Baz吗?

c++ contains composition default-copy-constructor

47
推荐指数
2
解决办法
3万
查看次数

在LLVM中调用隐式删除的复制构造函数

根据C++ 11规则,默认情况下会生成6个内容(默认构造函数,复制构造函数,移动构造函数,复制赋值,移动赋值和析构函数).根据第二个规则,当定义任何自定义副本,移动或析构函数时,不会生成这些默认操作.但是在我之后的代码中并非如此.但是这段代码无法编译错误

call to implicitly deleted copy constructor of 'Uni'
Run Code Online (Sandbox Code Playgroud)

当我为Uni编写自己的复制构造函数时,一切正常.(在代码中注释,供参考)

任何想法都非常感激.

最后,我在Mac上运行它,使用LLVM编译器运行Xcode.

非常感谢...

#include <iostream>

class A
{
public:
    A(int i) :num{i}
    {
        std::clog<< "ctor  A() num = " << num << "\n";

    }
    A( A const &aRef)
    :num{aRef.num}
    {
        std::clog << " copy ctor A( A const &aRef) num = " << num << "\n";
    }

    int value()
    {
        return num;
    }

private:
    int num;

};
class Uni
{

public:
    Uni(A* aptr) : up{aptr}
    {
        std::clog << " …
Run Code Online (Sandbox Code Playgroud)

c++ default-copy-constructor c++11

37
推荐指数
1
解决办法
5万
查看次数

C++的默认拷贝构造函数本质上是不安全的吗?迭代器根本上也不安全吗?

我曾经认为,当遵循最佳实践时,C++的对象模型非常强大.
就在几分钟前,我意识到我以前没有过.

考虑以下代码:

class Foo
{
    std::set<size_t> set;
    std::vector<std::set<size_t>::iterator> vector;
    // ...
    // (assume every method ensures p always points to a valid element of s)
};
Run Code Online (Sandbox Code Playgroud)

我写了这样的代码.直到今天,我还没有看到它的问题.

但是,考虑到它更多,我意识到这个类非常破碎:
它的copy-constructor和copy-assignment 复制里面的迭代器vector,这意味着它们仍然会指向旧的 set!毕竟新的不是真正的副本!

换句话说,我必须手动实现copy-constructor,即使这个类没有管理任何资源(没有RAII)!

这令我惊讶.我以前从未遇到过这个问题,我也不知道有什么优雅的方法来解决它.关于它的思考多一点,在我看来,那拷贝构造是默认不安全的 -事实上,在我看来那类应该不会是在默认情况下拷贝,但因为他们的实例变量之间的任何一种耦合的风险再现默认副本- 构造函数无效.

迭代器是否从根本上说不安全?或者,默认情况下类是否真的不可复制?

我在下面想到的解决方案都是不可取的,因为它们不会让我利用自动生成的复制构造函数:

  1. 为我编写的每个重要类手动实现一个拷贝构造函数.这不仅容易出错,而且对于编写复杂的类也很痛苦.
  2. 永远不要将迭代器存储为成员变量.这似乎是严重的限制.
  3. 默认情况下,对我写的所有类禁用复制,除非我能明确证明它们是正确的.这似乎完全违背了C++的设计,这对于大多数类型来说都具有值语义,因此是可复制的.

这是一个众所周知的问题,如果是这样,它是否有优雅/惯用的解决方案?

c++ iterator copy-constructor default-copy-constructor

36
推荐指数
6
解决办法
2544
查看次数

在C++ 0x中,非静态数据成员初始值设定项是否会覆盖隐式复制构造函数?

根据与相关的N2628,非静态数据成员初始化器可以被显式定义的构造函数覆盖,但它似乎对隐式定义的复制构造函数略显模糊.

特别是,我注意到使用Apple clang 3.0版时,行为会根据结构(或类)是否为POD而有所不同.

以下程序返回输出"1",表示复制构造函数忽略右侧,而是替换新的非静态数据成员初始值设定项(在此示例中,X :: a的布尔值为true) ).

#include <iostream>
#include <string>

struct X
{
    std::string string1;
    bool a = true;
};

int main(int argc, char *argv[])
{
    X x;
    x.a = false;
    X y(x);
    std::cout << y.a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是,令人困惑的是,如果你注释掉string1:

    // std::string string1;  
Run Code Online (Sandbox Code Playgroud)

然后行为按照我的预期工作(输出为"0"),大概是因为没有隐式生成的复制构造函数,因此复制了数据.

C++ 0x规范是否真的建议允许隐式定义的拷贝构造函数复制右侧的内容?这不是那么有用和不直观吗?我发现非静态成员初始化程序功能非常方便,但如果这是正确的行为,那么由于其棘手和不直观的行为,我将明确地避免使用该功能.

请告诉我,我错了?

更新:此错误已在Clang源存储库中修复.见此修订版.

更新:此错误在Apple clang 3.1版(标签/ Apple/clang-318.0.45)中出现(基于LLVM 3.1svn).这个版本的clang是作为Lion的Xcode 4.3的一部分发布的.

c++ clang default-copy-constructor c++11

14
推荐指数
1
解决办法
3621
查看次数

C#自动深层复制struct

我有一个结构,MyStruct有一个私有成员private bool[] boolArray;和一个方法ChangeBoolValue(int index, bool Value).

我有一个班,MyClass有一个领域public MyStruct bools { get; private set; }

当我从现有的MyStruct对象创建一个新的MyStruct对象,然后应用方法ChangeBoolValue()时,两个对象中的bool数组都会被更改,因为引用而不是引用的引用被复制到新对象.例如:

MyStruct A = new MyStruct();
MyStruct B = A;  //Copy of A made
B.ChangeBoolValue(0,true);
//Now A.BoolArr[0] == B.BoolArr[0] == true
Run Code Online (Sandbox Code Playgroud)

有没有办法强制副本实现更深层次的副本,或者有没有办法实现这个不会有同样的问题?

我特意将MyStruct设为结构,因为它是值类型,我不希望引用传播.

c# struct deep-copy default-copy-constructor

12
推荐指数
1
解决办法
3万
查看次数

存在引用时的赋值运算符和复制构造函数

我只是使用此代码试验参考:

class A
{
};

class B
{
public:
    B(A& a): m_a(a){}

    A& m_a;
};

int main()
{
    A a;
    B b(a);
    B b1 = b;
}
Run Code Online (Sandbox Code Playgroud)

我期待两者都B b1 = b;产生错误.相反,当我使用VS2008编译时,我只是收到警告

警告C4512:'B':无法生成赋值运算符

我理解为什么我会收到这个警告.但是编译器不应该为B b1 = b;语句生成错误吗?它就像它生成了复制构造函数但没有生成赋值运算符.这两者本身并不相互联系吗?当另一个无法生成时,为其中一个生成默认实现是否有意义?

c++ assignment-operator default-copy-constructor

10
推荐指数
1
解决办法
6149
查看次数

为什么不调用复制构造函数?

对于过于含糊的标题感到抱歉.(由于缺乏我的英语技能).请建议一个更好的标题.

请考虑以下代码.

struct A {
    typedef std::vector<double> State;

    //  template <class... Args>
    //  A(Args... args)
    //      : a(args...)
    //  {}

    template <class... Args>
    A(Args&&... args)
            : a(std::forward<Args>(args)...)
    {}

    A(const A&) = default;
    A(A&&) = default;

    State a;
};

int main(){

    A a(3,2);
    A b = a; // This line triggers an error!!
}
Run Code Online (Sandbox Code Playgroud)

Gcc 4.8.0无法使用错误消息进行编译 error: no matching function for call to 'std::vector<double>::vector(A&)' : a(std::forward<Args>(args)...).

我无法理解为什么这段代码错了.在我看来,编译器应该在行中调用复制构造函数A b = a;.

但是,如果我用注释的(它只是取值)替换构造函数.它确实编译.此外,现在不需要默认复制(和移动)构造函数的行.这里发生了什么?

c++ default-copy-constructor c++11

10
推荐指数
1
解决办法
329
查看次数

如果我用非const参数定义那些,我仍然可以得到默认的复制构造函数和operator =吗?

在C++中,如果我定义了一个复制构造函数和operator =对该类采用非const引用,那么编译器是否应该仍然为const引用提供默认版本?

struct Test {
  Test(Test &rhs);
  Test &operator=(Test &rhs);

private:
  // Do I still need to declare these to avoid automatic definitions?
  Test(const Test &rhs);
  Test &operator=(const Test &rhs);
};
Run Code Online (Sandbox Code Playgroud)

c++ const language-lawyer default-copy-constructor

7
推荐指数
1
解决办法
187
查看次数

Java对象复制最佳选择?

可能重复:
如何在Java中复制对象?

我需要在Java中复制一个对象(即通过值而不是通过引用复制对象,以便新对象不仅仅是对旧对象的引用).我厌倦了实现clonable并且更喜欢使用复制构造函数.但是,我需要复制的类有多个需要复制的成员变量(超过100个),所以在类中添加一个新的构造函数只是为了复制(只需要在我的应用程序的一部分中使用),这似乎是一个糟糕的解决方案由于它的长度很大.

有更好的解决方案吗?我应该只使用clone()吗?我可以创建一个复制构造函数,而不是将所有字段复制到1比1,我可以反思吗?谢谢.

我基本上只需要创建一个与旧对象相同的新对象,但是有一些(大约10个中的100个)字段已更改(但我仍然需要两个对象..所以新的对象不能作为对象的引用旧的).我对任何建议持开放态度.

java object deep-copy default-copy-constructor

5
推荐指数
2
解决办法
2万
查看次数

拦截C++隐式复制构造函数,或调用其功能

鉴于:

class Foo {

private:
    static int cntFoos;

    //... stuff...

public:
     Foo() { cntFoos++; }
     ~Foo() { cntFoos--; }
};
Run Code Online (Sandbox Code Playgroud)

......"stuff"可以是任何属性集.(想法是有一个该类实例的计数器)

然后:

Foo aFoo;
Foo twoFoo=aFoo;
Run Code Online (Sandbox Code Playgroud)

将调用自动复制构造函数,因此我会想念这个.

有没有办法让该计数器反映自动创建的新实例?如果我实现显式复制构造函数,我将不得不逐个分配所有属性.但是,我想要一个浅的成员副本.我不需要执行深层复制,因此实现显式复制构造函数似乎需要做很多工作.

c++ copy-constructor shallow-copy default-copy-constructor

5
推荐指数
2
解决办法
141
查看次数