【问题标题】:c++ Copy constructors and destructorsc++ 复制构造函数和析构函数
【发布时间】:2018-07-05 07:56:16
【问题描述】:

我正在学习 C++ 中的构造函数和析构函数;帮助我抓住我的错误,即使它们很愚蠢......

这里是我编写的使用 C++ 中的类执行加法的代码;这将创建 datatype num 的两个求和,并使用构造函数 sum() 来执行两个数字的求和;然而,当一切顺利时,我偶然发现为 num 创建了一个复制构造函数,(虽然不是必需的,但仍然可以练习)......如果没有类 sum 的动态对象,就不可能无论如何运行代码(不删除复制构造函数)...帮助我改进我的代码和我在下面代码中的错误; 我也想知道如何在这个程序中使用复制构造函数;问题是在析构函数中,删除操作在同一块内存上执行了多次(我想)

这是我的代码

#include<iostream>
#include<new>
using namespace std;
class num
{
public:
    int *a;
    num(int x)
    {
        try
        {
            a=new int;
        }
        catch(bad_alloc xa)
        {
            cout<<"1";
            exit(1);
        }
        *a=x;
    }
    num(){  }
    num(const num &ob)
    {
        try
        {
            a=new int;
        }
        catch(bad_alloc xa)
        {
            cout<<"1''";
            exit(2);
        }
        *a=*(ob.a);
    }
    ~num()
    { 
        cout<<"Destruct!!!";
        delete a;
    }
};


class sum:public num
{
 public:
     int add;
     sum(num n1,num n2)
     {
         add=*(n1.a)+*(n2.a);
     }
     int getsum()
     {
         return add;
     }
};

int main()
{
    num x=58;
    num y=82;
    sum *s=new sum(x,y);
    cout<<s->getsum();
    delete s;
    return 0;
}

【问题讨论】:

  • 对于代码审查,您可以考虑前往CodeReview Stackexchange
  • num(){ } 这是非常错误的。你不能让你的指针数据成员未初始化。
  • 为什么sum需要继承num? sum(num n1,num n2) 更喜欢由const num&amp; 代替。 sum(const num&amp; n1, const num&amp; n2)
  • 我认为num 不需要持有int *,而不仅仅是int。或者让它存在。只需在ints 上操作

标签: c++ class constructor destructor custom-data-type


【解决方案1】:

我可能会遗漏一些东西 - 没有使用 new/delete 太久,但尝试更正我注意到的所有内容。

附:始终使用智能指针。

#include <iostream>
#include <exception>
#include <new>

using namespace std;

int* allocate(const char* err_msg, int exit_code)
{
    int* a = nullptr;
    try
    {
        a = new int;
    }
    catch (bad_alloc&)
    {
        cout << err_msg << endl;
        exit(exit_code);
    }
    return a;
}

class num
{
    int* a = nullptr; // always should be initialized here

public:
    num() noexcept : a(nullptr) // or here
    {}

    /*explicit*/ num(int x) : a(allocate("1", 1))
    {
        *a = x;
    }

    num(const num& ob) : a(allocate("1''", 2))
    {
        *a = *(ob.a);
    }

    // rule of zero/three/five
    // default copy assignment will copy pointer and one int will be leaked and one will be deleted twice
    num& operator =(const num& ob)
    {
        if (&ob == this)
        {
            return *this;
        }

        *a = *(ob.a);
        return *this;
    }

    ~num()
    { 
        cout << "Destruct!!!";
        delete a;
        a = nullptr; // usefull for debug
    }

    int value() const
    {
        if (a == nullptr)
        {
            throw runtime_error("a == nullptr");
        }
        return *a;
    }
};

class sum
{
    int add = 0;

public:
    sum(const num& n1, const num& n2)
    {
        add = n1.value() + n2.value();
    }

    int getsum() const
    {
        return add;
    }
};

int main()
{
    const num x = 58;
    const num y = 82;
    const sum* s = new sum(x, y);
    cout << s->getsum() << endl;
    delete s;
    return 0;
}

【讨论】:

  • 感谢您的帮助;
  • 还有一个;因为我是构造函数和异常的新手,所以你能解释一下 num() noexcept: a(nullptr) 和 0 3 和 5 的规则吗?
  • 编译过程中出现几十个错误;我无法调试这些错误
  • @ArijitDey 您使用哪个编译器?下面是对 0/3/5 规则的解释:en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
  • @ArijitDey num() noexcept: a(nullptr) 是用 0 初始化 a 的默认构造函数。
猜你喜欢
  • 1970-01-01
  • 2013-04-17
  • 2011-04-03
  • 2010-12-16
  • 2020-05-14
  • 2013-10-13
  • 2012-04-10
  • 2012-11-14
  • 2016-09-09
相关资源
最近更新 更多