C++ 我的程序运行良好,我能够复制对象,但是当我使用复制分配(=)时,它仍然运行良好。为什么它没有给出错误?

C++ 我的程序运行良好,我能够复制对象,但是当我使用复制分配(=)时,它仍然运行良好。为什么它没有给出错误?,c++,codeblocks,C++,Codeblocks,我没有重载=操作符,但它在代码块中仍然运行良好。但是,当我在C++ shell上运行这个代码时,它编译成功,但是输出是空白的。有人能解释一下为什么它在代码块中运行良好,即使我没有为复制任务编写代码 还有一个问题 如果在第1行,我将返回类型改为string而不是string&它会显示一个关于临时变量的错误,但是如果我将第2行的代码改为dummydumy&abc:ptrnew string abc.print,尽管第1行的返回类型是string,程序运行正常。为什么会这样 class dummy {

我没有重载=操作符,但它在代码块中仍然运行良好。但是,当我在C++ shell上运行这个代码时,它编译成功,但是输出是空白的。有人能解释一下为什么它在代码块中运行良好,即使我没有为复制任务编写代码

还有一个问题

如果在第1行,我将返回类型改为string而不是string&它会显示一个关于临时变量的错误,但是如果我将第2行的代码改为dummydumy&abc:ptrnew string abc.print,尽管第1行的返回类型是string,程序运行正常。为什么会这样

class dummy {
  string* ptr;

 public:
  dummy(string ab) {
    ptr = new string;
    ptr = &ab;
  }
  ~dummy() { delete ptr; }
  string& print() { return *ptr; }  // line1
  dummy(dummy& abc) {
    ptr = new string;
    ptr = &(abc.print());
  }  // line2
  dummy(){};
};

int main() {
  dummy x("manzar");
  dummy y;
  y = x;

  cout << x.print();
  cout << "\n" << y.print();
}

我没想到它会运行良好,但它运行良好。它将内容从x复制到y。

编译器会自动为您生成赋值运算符,代码也会随之编译。有关何时发生和何时不发生的完整规则,请参阅。另见

您的代码不能在cpp shell上工作的原因可能是由于各种未定义的行为,包括但可能不限于:

违反三条规则: dummystring ab构造函数存储指向临时变量的指针。ptr=&ab;应为*ptr=ab; 您的dummydummy和abc复制构造函数应该是dummyconst dummy和abc,再次是ptr=&abc.print;应为*ptr=abc.print; 默认构造函数伪值应将ptr初始化为null ptr 打印应检查ptr是否为空。

是C++规范的一部分,默认情况下,如果没有定义用户副本分配操作符,则编译器将生成默认的复制赋值操作符。还有其他几个操作符和函数是这样自动生成的。其他的是默认构造函数、复制构造函数、移动构造函数、移动赋值运算符和析构函数

复制赋值的默认行为是复制对象的每个非静态成员-如果对象是POD类型,则此复制是否简单完成,或者是否确实执行成员级复制,但结果相同,这两者之间存在区别。对于不可能生成默认复制行为的情况,也存在一些复杂性:如果类的非静态成员为const;如果它有一个本身没有复制赋值运算符的非静态成员,等等

从C++11开始,您可以选择不让编译器通过将这些特殊成员函数指定给关键字delete来生成它们

例如,如果在代码中添加

dummy& operator=(const dummy &) = delete;

根据dummy的定义,程序将不再编译。

查看Howard Hinnants的编译器特殊成员表:记住,当你做了愚蠢的事情,或者当你做了违反语言规则并使你陷入未定义的行为时,编译器不需要警告你或出错,等。编译器通常只需要在代码出现语法错误且无法解析时停止您。除此之外,您所做的任何错误都由您承担,编译器不需要帮助您。也不需要告诉你什么时候它利用你的错误产生垃圾。您有责任了解并遵守所有的语言规则。编译器将根据语言规则,以默认行为为您合成某些成员函数,除非您自己实现它们或显式地=删除它们。仅仅因为有东西编译并运行,我的程序运行得很好,我很难相信这一点。你正在用指针做一些非常有趣的事情,你的代码会像筛子一样泄漏内存,并且会急切地加倍删除东西。你会从阅读一本书中受益。