Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/vb6/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当测试传递参数为左值复制、右值移动和按引用传递时,我观察到的行为问题_C++_C++17_Move - Fatal编程技术网

C++ 当测试传递参数为左值复制、右值移动和按引用传递时,我观察到的行为问题

C++ 当测试传递参数为左值复制、右值移动和按引用传递时,我观察到的行为问题,c++,c++17,move,C++,C++17,Move,在下面的代码中,我正在测试堆栈中的按左值传递(应该通过复制构造函数)、按右值传递(应该通过移动构造函数)和按引用传递(应该不调用构造函数)。但是,当执行行Func(MyType1())时,我认为MyType1()是一个r值,应该触发move构造函数。是的,在输出中,它显示它既不触发复制也不触发移动构造函数。它似乎通过pass或pass by左值或右值引用。为什么呢 第二个问题可能是因为我误解了可以在移动中完成。在我的类中,MyType1对象有一个字符数组。在复制/移动任务中,似乎对于数组,我只能

在下面的代码中,我正在测试堆栈中的按左值传递(应该通过复制构造函数)、按右值传递(应该通过移动构造函数)和按引用传递(应该不调用构造函数)。但是,当执行行Func(MyType1())时,我认为MyType1()是一个r值,应该触发move构造函数。是的,在输出中,它显示它既不触发复制也不触发移动构造函数。它似乎通过pass或pass by左值或右值引用。为什么呢

第二个问题可能是因为我误解了可以在移动中完成。在我的类中,MyType1对象有一个字符数组。在复制/移动任务中,似乎对于数组,我只能进行深度复制;不是通过调整指针来进行浅拷贝(我的目标是避免昂贵的数组元素逐个元素的深度拷贝)。理想情况下,在move c'tor中,我认为可以使新对象的数据指向堆栈中的现有数组,而使源堆栈对象中的数组指针为null。但这似乎只适用于堆对象指针。我错过什么了吗

在dc 0x7fff3727e114中

class MyType1
{
public:
  ~MyType1() 
  {
    cout << "in de " << this << "\n";
  }

  MyType1()
  {
    cout << "in dc " << this << "\n";
    for (int i = 0; i < 10; i++)
    {
      data[i] = 'a';
    }
  }

  MyType1(MyType1 &o)
  {
    cout << "in cc " << this << "\n ";
    // *data = *o.data; doesn't work, have to deep copy?
  }

  MyType1(MyType1 &&o)
  {
    cout << "in mc "<< this << "\n ";
    // *data = *o.data; doesn't work, have to deep copy? also can't free source array?
  }

  void Print()
  {
    for (int i = 0; i < 10; i++)
    {
      cout << data[i] << " ";
    }

    cout << "\n";
  }

  char data[10];
};

void Func(MyType1 other)
{
  cout << "in Func\n";
  other.Print();
}

void FuncRef(MyType1& other)
{
  cout << "in FuncRef\n";
  other.Print();
}
    
int main()
{
  MyType1 t;
  Func(t);
  Func(std::move(t));
  Func(MyType1());
  FuncRef(t);
}
在cc 0x7fff3727e11e中

本币

在de 0x7fff3727e11e中

在mc 0x7fff3727e11e中

本币

在de 0x7fff3727e11e中

在dc 0x7fff3727e11e中

在函数中

a aa

在de 0x7fff3727e11e中

在FuncRef中

a a a a a a a a a a a a a

在de 0x7fff3727e114中

class MyType1
{
public:
  ~MyType1() 
  {
    cout << "in de " << this << "\n";
  }

  MyType1()
  {
    cout << "in dc " << this << "\n";
    for (int i = 0; i < 10; i++)
    {
      data[i] = 'a';
    }
  }

  MyType1(MyType1 &o)
  {
    cout << "in cc " << this << "\n ";
    // *data = *o.data; doesn't work, have to deep copy?
  }

  MyType1(MyType1 &&o)
  {
    cout << "in mc "<< this << "\n ";
    // *data = *o.data; doesn't work, have to deep copy? also can't free source array?
  }

  void Print()
  {
    for (int i = 0; i < 10; i++)
    {
      cout << data[i] << " ";
    }

    cout << "\n";
  }

  char data[10];
};

void Func(MyType1 other)
{
  cout << "in Func\n";
  other.Print();
}

void FuncRef(MyType1& other)
{
  cout << "in FuncRef\n";
  other.Print();
}
    
int main()
{
  MyType1 t;
  Func(t);
  Func(std::move(t));
  Func(MyType1());
  FuncRef(t);
}
类MyType1
{
公众:
~MyType1()
{

这不是对你问题的完全回答,但(我认为)触及了你误解的核心

考虑以下结构:

struct One {
   char data[10];
};
该结构有10个字节长。每个
One
类型的对象包含一个由10个元素组成的数组。不是指向数组的指针,而是一个实际数组

所以,当你说你想做一个“浅层复制”时,这意味着什么?你不能将数组“指向”另一个数组-这不是数组的工作方式。如果你有一个指针,你可以这样做,但是struct
One
不存储指针,只存储一个数组。(是的,您可以创建指向
数据的指针,但不能将该指针存储在
One
类型的对象中)


将数组作为
One
对象的一部分也意味着数组的存储只与它所属的对象存在相同的时间。因此,即使您可以“重新指向”数组,当原始(源)对象被销毁(并重新使用存储)时,也会导致问题。

您在这里问了两个问题:

<>代码> >代码(Fyc)( >在默认CTER后没有调用移动Ctor,答案是“复制删除”:C++标准允许跳过复制或移动构造函数,而不是使用原始对象(从C++ 17开始,在某些情况下强制删除)。规则在标准的不同版本之间发生变化,并且非常复杂。您永远不应该依赖于调用的复制/移动构造函数
  • 您的理解是正确的:如果不使用heap,就无法使用move构造函数进行优化