我没有重载(=
)运算符,但它在代码块中仍然可以正常运行。但是,当我在C ++ shell上运行此代码时,它成功编译,但是输出为空。有人可以解释一下,即使我没有为拷贝分配编写代码,为什么它仍可以在代码块中正常运行?
还有另一个问题...
如果在第1行上将返回类型更改为string
而不是string&
,它将显示错误(关于临时变量),但是如果我将第2行的代码更改为dummy(dummy& abc : ptr(new 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
。
答案 0 :(得分:2)
代码会在编译器自动为您生成赋值运算符时进行编译。有关何时发生和不发生的完整规则,请参见https://en.cppreference.com/w/cpp/language/copy_assignment。另请参见What is The Rule of Three?
您的代码无法在cpp shell上运行的原因可能是由于各种未定义的行为,包括(但可能不限于):
dummy(string ab)
构造函数存储一个指向临时变量的指针。 ptr = &ab;
应该是*ptr = ab;
dummy(dummy& abc)
副本构造函数应为dummy(const dummy& abc)
,再次ptr = &(abc.print());
应该为*ptr = abc.print();
dummy()
应该将ptr
初始化为nullptr
print()
应该检查ptr
是否不为空。答案 1 :(得分:2)
这是C ++规范的一部分,默认情况下,如果类定义中未包含用户定义的副本分配运算符,则编译器将生成默认的副本分配运算符。这样会自动生成其他几个运算符和函数。其他的是默认构造函数,副本构造函数,move构造函数,move赋值运算符和析构函数。
副本分配的默认行为是复制对象的每个非静态成员-如果对象是POD类型,还是真正执行一个对象,则此副本是“简单地”完成的逐成员复制,但结果相同。对于无法生成默认复制行为的情况,还存在一些复杂性:如果类具有const的非静态成员,则该类为非静态成员。如果它具有一个非静态成员,而该成员本身没有副本分配运算符,等等。
从C ++ 11开始,您可以选择不让编译器通过将它们分配给关键字 delete 来生成任何这些特殊成员函数。
例如,在代码中添加
dummy& operator=(const dummy &) = delete;
按照虚拟的定义,程序将不再编译。