-2
  1. 我已经覆盖了默认的复制构造函数和赋值运算符,只打印而不返回任何东西。
  2. 然而,该类工作正常,即它被正确复制和分配。
  3. 如您所见,display()方法也被正确调用。(我期待崩溃或分段错误,因为复制构造函数和赋值运算符被覆盖并且什么都不做。
  4. 我已经用不同的编译器(包括在线编译器)编译了相同的内容,但输出仍然保持不变。

我的问题:为什么类工作正常?不显示任何错误?我期待它崩溃或出现故障,例如输出垃圾值。

'

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
4

1 回答 1

0

看起来我找到了原因:
感谢@Igor Tandetnik,他在提出问题的同一天在评论中提到了同样的事情。但是,由于评论很简短,而且我仍处于学习阶段,因此我无法从评论中了解全貌。因此,决定写下答案,并进行一些解释。这对像我这样的人会有帮助,总有一天:)。

原因:
- 我没有使用类中的任何数据成员。
- 我只使用上面代码中的类方法。因为,所有对象都使用相同的类方法(即,类方法是每个类,而不是每个对象。)
- 复制构造函数的主要动机是将数据成员从类的一个对象复制到另一个对象。- 我没有为每个对象创建的类声明任何非静态数据成员。为上述声明非静态成员肯定会导致类的未定义行为。此类数据成员具有垃圾值。
- 因此,上述代码适用于不正确的复制构造函数和移动赋值运算符。

下面是由于不正确的赋值运算符和复制构造函数而为数据成员提供垃圾值的代码。

//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();
}

底线:复制构造函数、移动构造函数、赋值运算符只有在类具有非静态数据成员时才最有意义。

于 2018-08-15T04:55:02.760 回答