为什么我的 Class 工作正常,即使在 return 将垃圾值作为 return 赋值运算符和空复制构造函数之后?
Why my Class work properly, Even after returning junk value as return for assignment operator and empty copy constructor?
- 我已经重写了默认的复制构造函数和赋值运算符,只打印但不返回任何东西。
- 然而,class 工作正常,即它被正确复制和分配。
- 如您所见,display() 方法也被正确调用。 (我期待崩溃或分段错误,因为复制构造函数和赋值运算符被覆盖并且什么都不做。
- 我用不同的编译器编译了相同的内容,包括在线编译器,但输出仍然相同。
我的问题:
为什么 class 可以正常工作?不显示任何错误?
我原以为它会崩溃或出现故障,例如输出垃圾值。
'
class Pizza
{
public:
Pizza(std::string string) { std::cout << "Ctor :" << string << std::endl; }
~Pizza() { std::cout << "Dtor" << std::endl; }
Pizza(const Pizza& rhs){ std::cout << "Copy Constructor" << std::endl; }
Pizza& operator=(const Pizza& rhs){ std::cout << "Assignment Operator" << std::endl;}
void display(){std::cout << "Display method is called on Pizza" << std::endl; }
};
int main()
{
Pizza pizza = Pizza("1");
Pizza tizza = pizza;
tizza = pizza;
pizza.display();
tizza.display();
}'
在 windows 10 和其他编译器上使用 g++(Mingw 编译器)的代码的输出也是:
Ctor :1
Copy Constructor
Assignment Operator
Display method is called on Pizza
Display method is called on Pizza
Dtor
Dtor
看来我找到原因了:
感谢@Igor Tandetnik,他在提问的同一天在评论中提到了同样的事情。但是,由于评论很简短,而且我仍处于学习阶段,因此我无法从评论中了解全貌。因此,决定写下答案,并作一些解释。这对像我这样的人会有帮助,总有一天 :) .
原因:
- 我没有使用 class.
中的任何数据成员
- 我在上面的代码中只使用了 class 方法。因为,所有对象都使用相同的 class 方法(即,class 方法是每个 class,而不是每个对象。)
- 复制构造函数的主要动机是将数据成员从 class 的一个对象复制到另一个对象。
- 我没有为每个对象创建的 class 声明任何非静态数据成员。为上述声明非静态成员肯定会导致 class 的未定义行为。这样的数据成员具有垃圾值。
- 因此,上面的代码适用于不正确的复制构造函数和移动赋值运算符。
下面的代码会因为不正确的赋值运算符和复制构造函数而为数据成员提供垃圾值。
//g++ 5.4.0
#include <iostream>
class Pizza
{
public:
Pizza(std::string string, int data) : m_string(string), m_data(data) { std::cout << "Ctor :" << string << std::endl; }
~Pizza() { std::cout << "Dtor" << std::endl; }
void set(std::string string, int data) { m_string = string; m_data = data; }
Pizza(const Pizza& rhs){ std::cout << "Copy Constructor" << std::endl; }
Pizza& operator=(const Pizza& rhs){ std::cout << "Assignment Operator" << std::endl;}
void display()
{
std::cout << "Display method is called on Pizza" << std::endl;
std::cout << "string: " << m_string << " Data: " << m_data << std::endl;
}
private:
std::string m_string;
int m_data;
};
int main()
{
Pizza pizza = Pizza("Test", 99);
Pizza tizza = pizza;
tizza = pizza;
pizza.display();
tizza.display();
}
底线: 复制构造函数、移动构造函数、赋值运算符只有在 class 具有非静态数据成员时才最有意义。
- 我已经重写了默认的复制构造函数和赋值运算符,只打印但不返回任何东西。
- 然而,class 工作正常,即它被正确复制和分配。
- 如您所见,display() 方法也被正确调用。 (我期待崩溃或分段错误,因为复制构造函数和赋值运算符被覆盖并且什么都不做。
- 我用不同的编译器编译了相同的内容,包括在线编译器,但输出仍然相同。
我的问题: 为什么 class 可以正常工作?不显示任何错误? 我原以为它会崩溃或出现故障,例如输出垃圾值。
'
class Pizza
{
public:
Pizza(std::string string) { std::cout << "Ctor :" << string << std::endl; }
~Pizza() { std::cout << "Dtor" << std::endl; }
Pizza(const Pizza& rhs){ std::cout << "Copy Constructor" << std::endl; }
Pizza& operator=(const Pizza& rhs){ std::cout << "Assignment Operator" << std::endl;}
void display(){std::cout << "Display method is called on Pizza" << std::endl; }
};
int main()
{
Pizza pizza = Pizza("1");
Pizza tizza = pizza;
tizza = pizza;
pizza.display();
tizza.display();
}'
在 windows 10 和其他编译器上使用 g++(Mingw 编译器)的代码的输出也是:
Ctor :1
Copy Constructor
Assignment Operator
Display method is called on Pizza
Display method is called on Pizza
Dtor
Dtor
看来我找到原因了:
感谢@Igor Tandetnik,他在提问的同一天在评论中提到了同样的事情。但是,由于评论很简短,而且我仍处于学习阶段,因此我无法从评论中了解全貌。因此,决定写下答案,并作一些解释。这对像我这样的人会有帮助,总有一天 :) .
原因:
- 我没有使用 class.
中的任何数据成员
- 我在上面的代码中只使用了 class 方法。因为,所有对象都使用相同的 class 方法(即,class 方法是每个 class,而不是每个对象。)
- 复制构造函数的主要动机是将数据成员从 class 的一个对象复制到另一个对象。
- 我没有为每个对象创建的 class 声明任何非静态数据成员。为上述声明非静态成员肯定会导致 class 的未定义行为。这样的数据成员具有垃圾值。
- 因此,上面的代码适用于不正确的复制构造函数和移动赋值运算符。
下面的代码会因为不正确的赋值运算符和复制构造函数而为数据成员提供垃圾值。
//g++ 5.4.0
#include <iostream>
class Pizza
{
public:
Pizza(std::string string, int data) : m_string(string), m_data(data) { std::cout << "Ctor :" << string << std::endl; }
~Pizza() { std::cout << "Dtor" << std::endl; }
void set(std::string string, int data) { m_string = string; m_data = data; }
Pizza(const Pizza& rhs){ std::cout << "Copy Constructor" << std::endl; }
Pizza& operator=(const Pizza& rhs){ std::cout << "Assignment Operator" << std::endl;}
void display()
{
std::cout << "Display method is called on Pizza" << std::endl;
std::cout << "string: " << m_string << " Data: " << m_data << std::endl;
}
private:
std::string m_string;
int m_data;
};
int main()
{
Pizza pizza = Pizza("Test", 99);
Pizza tizza = pizza;
tizza = pizza;
pizza.display();
tizza.display();
}
底线: 复制构造函数、移动构造函数、赋值运算符只有在 class 具有非静态数据成员时才最有意义。