为什么这里不调用复制构造函数
Why is copy constructor not called here?
我正在快速C++复习课程。 试图复习一些基本概念。 当我运行以下程序时,我看到两个问题:1. 由于某种原因,没有调用复制 CC。2. 函数 testCC() 退出后,程序由于某种原因崩溃。
任何帮助不胜感激!
class A
{
public:
A()
{
this->ptr = new int[10];
}
~A()
{
delete[] ptr;
}
A(const A &obj)
{
std::cout << "Copy CC calledn";
for (int i = 0; i < 10; i++)
{
ptr[i] = obj.ptr[i];
}
}
void set()
{
for (int i = 0; i < 10; i++)
{
ptr[i] = rand() % 10;
}
}
void print()
{
for (int i = 0; i < 10; i++)
{
std::cout << ptr[i] << " ";
}
std::cout << "n";
}
private:
int *ptr;
};
void testCC()
{
A a1,a2;
a1.set();
std::cout << "Contents of a1n";
a1.print();
a2 = a1;
std::cout << "Contents of a2n";
a2.print();
}
复制赋值和复制构造不是一回事。
a2 = a1
调用a2.operator=(a1)
(复制赋值),而不是复制构造函数。 您可以在 A
类中像这样定义复制赋值运算符:
A & operator=(A const & obj)
{
// Perform copy...
return *this;
}
无论哪种方式,您的复制构造函数都是错误的(您在使用它之前不会初始化ptr
),因此即使使用了您的复制构造函数,您也会调用未定义的行为并可能崩溃。
问题,我相信是这一行:
a2 = a1;
此行不调用 A 的复制构造函数,因为 a2 已存在。 (目前尚未构建它。 相反,它调用 A 的赋值运算符:A& operator=(const A&)
由于尚未定义赋值运算符,因此将获得默认编译器生成的赋值运算符,该运算符仅执行按位复制。 因此,a2 和 a1 最终都包含相同的ptr
值。 这也是您的程序崩溃的原因。 当testCC
退出时,a1 和 a2 都会被销毁,并且都试图释放同一个数组。
>a2 = a1
调用复制赋值运算符,而不是复制构造函数。您的类没有实现复制赋值运算符,因此编译器会生成一个默认运算符,该运算符仅执行成员级复制。a1 = a2
后,您有两个指向同一内存的ptr
副本,当testCC
返回时,a
和b
都会尝试删除这些副本。此双重删除导致崩溃。
可以通过编写A a2(a1)
或A a2 = a1
来测试复制构造函数
a2 = a1;
是作业而不是复制。
A a3 = a1;
这将调用复制构造函数。
编写赋值运算符
A & operator=(const A & obj)
{
std::cout << "Assingment calledn";
for (int i = 0; i < 10; i++)
{
ptr[i] = obj.ptr[i];
}
return *this;
}
这将由
a2 = a1;
这不会调用复制构造函数,因为它是一个构造函数,应该在创建对象并且已经创建了 a2 时调用。
崩溃的可能原因可能是在testCC之后,当调用析构函数时,a1的析构函数将释放指针,但由于a2的指针也指向同一位置,在析构函数中删除它时,它会崩溃。
因此,在复制任何内容之前始终构造对象。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用