C++不必要的破坏

发布于 2024-10-12 11:36:49 字数 704 浏览 7 评论 0原文

有人可以解释为什么当c完成构造时,b(c的成员)的析构函数被调用,而d被析构 - 正如预期的那样 - c 的析构函数何时被调用?

#include <iostream>

using namespace std;

class A
{
public:
    int a, b;
};

class B
{
public:
    A* array[10];
    B()
    {
        for(int i = 0 ; i < 10 ; i++)
            array[i] = new A();
    }
    ~B()
    {
        for(int i = 0 ; i < 10 ; i++)
            delete array[i];
    }
};

class C
{
public:
    B b;
    B* d;
    C()
    {
        b = B();
    }
    ~C()
    {
            delete d;
    }
};

int main()
{
    B b = B();
    C c = C();
    cout << "Ashlamish" << endl;
    system("pause");
    return 0;
}

Can somebody explain why when c finishes construction, the destructor of b (member of c) is called, while d is destructed - as expected - when c's destructor is called ?

#include <iostream>

using namespace std;

class A
{
public:
    int a, b;
};

class B
{
public:
    A* array[10];
    B()
    {
        for(int i = 0 ; i < 10 ; i++)
            array[i] = new A();
    }
    ~B()
    {
        for(int i = 0 ; i < 10 ; i++)
            delete array[i];
    }
};

class C
{
public:
    B b;
    B* d;
    C()
    {
        b = B();
    }
    ~C()
    {
            delete d;
    }
};

int main()
{
    B b = B();
    C c = C();
    cout << "Ashlamish" << endl;
    system("pause");
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

日记撕了你也走了 2024-10-19 11:36:49

b = B() 中,您构建了类 B 的一个新的临时实例,将一个副本分配给 b,然后对该临时实例进行解构。

In b = B() you're constucting a new temporarty instance of class B, assigning a copy to b, then the temporary instance is descructed.

江湖正好 2024-10-19 11:36:49

因为在 C 的构造函数中,您在 c = B(); 行中创建了一个临时 B 对象,并且当赋值完成时,该临时对象将被销毁。

Because in the constructor of C, you are creating a temporary B object in the line c = B(); and when the assignment is complete, that temporary object is being destroyed.

寄离 2024-10-19 11:36:49

我认为你想像这样声明 c :

C c;

这将构造一个名为 c 的对象,该对象将在作用域退出时被破坏。
另一方面,你拥有什么;

C c = C();

将构造一个 C 类型的匿名对象,用它复制构造 c 并立即销毁该匿名对象。 c 仍将在作用域结束时被破坏。

I think you want to declare c like this:

C c;

This will construct an object named c which will be destructed on scope exit.
On the other hand, what you have;

C c = C();

will construct an anonymous object of type C, copy construct c with it and immediately destruct the anonymous object. c will still be destructed at the end of the scope.

迷迭香的记忆 2024-10-19 11:36:49

在 C 的构造函数中,它

    b = B();

的作用是:

  • 构造 B 类型的临时对象
  • 通过使用默认赋值运算符将此对象分配给 b
  • 销毁临时对象

要修复此问题,请在 C 的构造函数中使用初始化列表,如下所示:

    C() : b()
    { }

或只是将构造函数留空,这样它将使用默认构造函数。

In the constructor of C you have

    b = B();

what this does is:

  • construct temporary object of type B
  • assign this object to b by the use of default assignment operator
  • destroy the temporary object

To fix this use initialization list in the constructor of C like this:

    C() : b()
    { }

or just leave the constructor empty, that way it will use the default constructor.

月亮坠入山谷 2024-10-19 11:36:49

C 构造函数中的 b = B(); 行实例化了 B 类型的新对象,并使用 B的复制构造函数来复制 C::b 中的此类对象。

C 构造函数返回时,b 不会被销毁,但用于调用 bB 临时对象复制构造函数是。

您可以删除此类指令,以避免实例化 B 临时对象,在这种情况下,b 将仅使用默认构造函数构造。

The line b = B(); in C constructor instantiates a new object of type B, and uses B's copy constructor to copy such object in C::b.

When C constructor returns b doesn't get destroyed, but the B temporary object used to call b's copy constructor is.

You could just remove such instruction in order to avoid instantiation of a B temporary, in this case b will just be constructed using the default constructor.

情话墙 2024-10-19 11:36:49

临时 B 的析构函数被调用 (b = B();),而不是成员 b 的析构函数。这行完全可以删除,因为 b 已经在隐式初始化列表中默认构造

destructor of temporary B is called (b = B();), not of member b. this line can be removed at all because b is already default constructed in implicit initialization list

触ぅ动初心 2024-10-19 11:36:49

你在这里犯下了大罪 - 不遵守3规则

你的 B 需要一个析构函数,但没有实现复制和赋值。

然后你继续通过实际做作业来复合错误。

您还可以继续删除未初始化的指针。 (如果 d 为 NULL 就可以了,但没有理由为什么它应该是 NULL)。

您还需要实现复制构造,特别是当您的编译器很可能选择将其用于上述构造时,尽管它实际上可能不会这样做。

You have committed here a cardinal sin - not obeying the rule of 3.

Your B needs a destructor but does not implement copying and assignment.

You then go ahead and compound the error by actually doing an assignment.

You also go on to delete an uninitialised pointer. (It would be fine if d were NULL but there is no reason why it should be).

You also need to implement copy-construction, especially as your compiler may well choose to use it for the above constructs, although it probably won't actually do so.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文