标签: copy-constructor

为什么复制赋值运算符必须返回引用/ const引用?

在C++中,我不清楚从复制赋值运算符返回引用的概念.为什么复制赋值运算符不能返回新对象的副本?另外,如果我上课A,还有以下内容:

A a1(param);
A a2 = a1;
A a3;

a3 = a2; //<--- this is the problematic line
Run Code Online (Sandbox Code Playgroud)

operator=定义如下:

A A::operator=(const A& a)
{
    if (this == &a)
    {
        return *this;
    }
    param = a.param;
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

c++ operator-overloading copy-constructor assignment-operator

62
推荐指数
4
解决办法
4万
查看次数

动态分配对象数组

这是一个初学者的问题,但我很长一段时间没有做过C++,所以这里......

我有一个包含动态分配数组的类,比方说

class A
{
    int* myArray;
    A()
    {
        myArray = 0;
    }
    A(int size)
    {
        myArray = new int[size];
    }
    ~A()
    {
        // Note that as per MikeB's helpful style critique, no need to check against 0.
        delete [] myArray;
    }
}
Run Code Online (Sandbox Code Playgroud)

但现在我想创建一个动态分配的这些类的数组.这是我目前的代码:

A* arrayOfAs = new A[5];
for (int i = 0; i < 5; ++i)
{
    arrayOfAs[i] = A(3);
}
Run Code Online (Sandbox Code Playgroud)

但这种情况非常糟糕.因为在循环迭代完成时,A(通过A(3)调用)创建的新对象会被破坏for,这意味着myArrayA实例的内部delete []变为-ed.

所以我认为我的语法必定是非常错误的?我想有一些看起来像矫枉过正的修复,我希望避免:

  • 为...创建复制构造函数A …

c++ pointers destructor memory-management copy-constructor

56
推荐指数
3
解决办法
13万
查看次数

复制构造函数和赋值运算符

如果我覆盖operator=,复制构造函数会自动使用new运算符吗?同样,如果我定义了一个拷贝构造函数,会operator=自动"继承"拷贝构造函数的行为吗?

c++ constructor operators copy-constructor assignment-operator

50
推荐指数
3
解决办法
6万
查看次数

是否复制了POD类型的填充字节?

假设我有这样的POD类型:

struct A {
    char a;
    int b;
};
Run Code Online (Sandbox Code Playgroud)

在我的系统上,sizeof(A) == 8即使sizeof(char) == 1sizeof(b) == 4.这意味着数据结构有3个未使用的字节.

现在假设我们这样做

A x = ...;
A y =x;
Run Code Online (Sandbox Code Playgroud)

题:

难道是保证所有8个字节的xy将是相同的,即使是那些3分未使用的?

同样,如果我将某些A对象的底层字节转移到另一个不理解其含义或结构的程序,并将它们视为一个8字节的数组,那么其他程序可以安全地比较两个As的相等吗?

注意:在使用gcc 7的实验中,似乎会复制这些字节.我想知道这是否有保证.

c++ copy-constructor

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

什么是C++中的转换构造函数?它是为了什么?

我听说C++有一些叫做"转换构造函数"或"转换构造函数"的东西.这些是什么,它们的用途是什么?我在这段代码中看到了它:

class MyClass
{
  public:
     int a, b;
     MyClass( int i ) {}
}

 int main()
{
    MyClass M = 1 ;
}
Run Code Online (Sandbox Code Playgroud)

c++ constructor copy-constructor

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

在c ++中使用私有拷贝构造函数有什么用处

为什么人们定义私有拷贝构造函数?

何时使复制构造函数和赋值运算符私有化是一个好的设计?

如果有哪个是指针或处理到一个唯一的对象(如文件名)类没有成员,然后笏其他情况下都存在,其中私人拷贝构造函数是一个好主意?

同样的问题适用于赋值运算符.鉴于大多数C++围绕复制对象并通过引用传递,是否有任何涉及私有拷贝构造函数的好设计?

c++ copy-constructor assignment-operator

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

为什么用户定义的move-constructor会禁用隐式复制构造函数?

当我正在阅读boost/shared_ptr.hpp时,我看到了这段代码:

//  generated copy constructor, destructor are fine...

#if defined( BOOST_HAS_RVALUE_REFS )

// ... except in C++0x, move disables the implicit copy

shared_ptr( shared_ptr const & r ): px( r.px ), pn( r.pn ) // never throws
{
}

#endif
Run Code Online (Sandbox Code Playgroud)

注释"生成复制构造函数,析构函数是否正常,除了在C++ 11中,移动禁用隐式副本"是什么意思?我们是否总是自己编写副本来防止C++ 11中出现这种情况?

c++ boost copy-constructor rvalue-reference c++11

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

仅使用基类指针复制派生实体(没有详尽的测试!) - C++

鉴于由派生类的继承过多基类,这需要您通过基类指针,每个实体管理这些程序结构.当只知道基类指针时,是否有一种简单的方法来复制整个派生对象?

环顾四周似乎可能(如果非常繁琐)使用dynamic_cast调用来检查基类指针是否可以作为适当的派生类进行转换,然后使用派生类的复制构造函数复制它.然而,这并不是一个真正的最佳解决方案,部分原因是由于过度使用了dynamic_cast,而且它会让人感到头疼,难以维持和扩展.

我遇到的另一个更优雅的解决方案如下:

class Base
{
public:
   Base(const Base& other);
   virtual Base* getCopy();
   ...
}

class Derived :public Base
{
   Derived(const Derived& other);
   virtual Base* getCopy();
   ...
}

Base* Base::getCopy()
{
   return new Base(*this));
}

Base* Derived::getCopy()
{
   return static_cast<Base*>(new Derived(*this));
}
Run Code Online (Sandbox Code Playgroud)

然后通过调用getCopy()指向任何派生对象的Base类指针,仍然可以返回一个基类指针,但也复制了整个派生对象.这种方法感觉更易于维护,因为它只需要getCopy()在所有派生类中使用类似的函数,并且不需要针对所有可能的派生对象进行测试.

从本质上讲,这是明智的吗?或者有更好,更简洁的方式吗?

c++ inheritance pointers copy-constructor

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

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
查看次数

为什么隐式复制构造函数调用基类复制构造函数而定义的复制构造函数不?

考虑一个类层次结构,其中A是基类并B派生自A.

如果未定义复制构造函数B,编译器将合成一个.调用时,此复制构造函数将调用基类复制构造函数(即使是合成的构造函数,如果用户没有提供).

#include <iostream>

class A {
    int a;
public:
    A() {
        std::cout << "A::Default constructor" << std::endl;
    }

    A(const A& rhs) {
        std::cout << "A::Copy constructor" << std::endl;
    }
};

class B : public A {
    int b;
public:
    B() {
        std::cout << "B::Default constructor" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    std::cout << "Creating B" << std::endl;
    B b1;
    std::cout << "Creating …
Run Code Online (Sandbox Code Playgroud)

c++ language-design copy-constructor

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