C++ 创建class类型的动态分配数组,其中该类不能有默认构造函数

C++ 创建class类型的动态分配数组,其中该类不能有默认构造函数,c++,C++,我有一个作业,我将列出练习,然后列出我的解决方案,以及我很好地请求您帮助我理解和解决的问题 Point类描述二维/三维空间中的点,并包含 ·x-整数属性 ·y-整数属性 ·z-整数属性 ·默认情况下初始化属性 ·类没有默认构造函数 ·该类有两个构造函数:一个请求X和Y,另一个请求所有值 ·该类为这三个值提供了get和set方法 每个几何图形由给定数量的角定义(连接它们的线定义几何图形) AbstractGeometricFigure类包含 ·地物类型-字符串属性 ·is2D-布尔属性 ·角数-整

我有一个作业,我将列出练习,然后列出我的解决方案,以及我很好地请求您帮助我理解和解决的问题

  • Point类描述二维/三维空间中的点,并包含

    ·x-整数属性 ·y-整数属性 ·z-整数属性 ·默认情况下初始化属性 ·类没有默认构造函数 ·该类有两个构造函数:一个请求X和Y,另一个请求所有值 ·该类为这三个值提供了get和set方法

  • 每个几何图形由给定数量的角定义(连接它们的线定义几何图形)

  • AbstractGeometricFigure类包含

    ·地物类型-字符串属性 ·is2D-布尔属性 ·角数-整数属性 ·角点阵列-点对象的动态向量 ·area()-一种纯虚拟方法,用于确定​​几何图形 ·Perfecture()-确定边界面积的纯虚拟方法​​几何图形 ·getCorners()-使用模板(X,Y)显示二维几何图形的角点,使用模板(X,Y,Z)显示三维几何图形的角点的方法 ·addCorner()-添加新角点的方法

  • 我偶然发现addCorner()方法,因为我需要创建另一个数组,向其中添加新的角点。为了创建Point类类型的动态数组,编译器告诉我为Point类创建默认构造函数。正如你在上面看到的,我是不被允许这样做的。如何创建另一个数组来复制Corners数组,并在其末尾添加新值,而不实现类Point的默认构造函数?即使我不必创建另一个数组,在考试时也可能有这样的练习,我想知道,如果我有一个class类型的动态数组,并且不允许我实现该类的默认构造函数,我应该怎么做

    这是我到目前为止的代码:

    #include<iostream>
    #include<string>
    using namespace std;
    
    class MySpecialException:public exception
    {
    public:
        MySpecialException(string msg) :exception(msg.data())
        {
    
        }
    };
    
    class Point
    {
        int x=0;
        int y=0;
        int z=0;
    public:
        Point(int X,int Y)
        {
            this->x = X;
            this->y = Y;
        }
    
        Point(int X,int Y,int Z)
        {
            this->x = X;
            this->y = Y;
            this->z = Z;
        }
    
        int getX()
        {
            return this->x;
        }
    
        int getY()
        {
            return this->y;
        }
        int getZ()
        {
            return this->z;
        }
    
    
        void setX(int xcs)
        {
            this->x = xcs; 
        }
    
        void setY(int igrec)
        {
            this->y = igrec;
        }
    
        void setZ(int zet)
        {
            this->z = zet;
        }
    
    };
    
    
    class AbstractGeometricFigure
    {
        string Figuretype;
        bool is2D;
        int nbcorners;
        Point* Corners;
    public:
        virtual int area() = 0;
        virtual int perimeter() = 0;
    
        void getCorners() {
            for (int i = 0; i < nbcorners; ++i) {
                cout << "(" << Corners[i].getX() << ", " << Corners[i].getY();
                if (is2D) {
                    cout << ")\n";
                }
                else {
                    cout << ", " << Corners[i].getZ() << ")\n";
                }
            }
        }
    
        void addCorner(int newcorner)
        {
            if (Corners!=NULL)
            {
                Point* varfuri = new Point[nbcorners];
            }
        }
    
    };
    

    如果你真的想将<代码> Valffi 作为包含<代码>点>代码>的数组,直接作为元素,它具有所有的语义(例如指针算术等),并且你不允许使用<代码> STD::vector < /C>或类似的库容器,那么目前在C++中没有完全合法的方式。 理论上,您可以使用

    运算符new
    分配未初始化的内存块,并使用单元素放置new(通过各种
    std::uninitialized.*
    标准库函数)来模拟
    std::vector
    的行为,但是从技术上讲,不允许使用指向第一个元素的指针,就像它是指向元素数组的指针一样,尽管在实践中这可能会很好

    如果您不需要数组语义,那么您可以实现一个链表或类似的非连续容器并使用它。请参阅下面的注释,了解比链表更简单的替代方法

    根据您给定的需求,这些似乎是唯一的解决方案


    正如@interjay在这个答案下面的评论中所指出的,您也可以只分配一个初始化为
    nullptr
    的指针数组,而不是一个链表:

    auto varfuri = new Point*[nbcorners]{};
    

    其中考虑<代码> null ptr>代码>替换默认构造状态,然后构造并添加元素< <代码>新< /代码>:

    varfuri[i] = new Point(/*constructor arguments*/);
    
    完成后,确保
    delete
    每个元素和
    delete[]
    数组分配

    然而,这也有不同于直接分配元素数组的语义。然而,作为一项任务,它似乎更为合理

    在实践中,这些
    新的
    使用都不会被认为是正确的,因为在出现异常的情况下,它们不会正常工作。相反,至少要将两个分配包装在
    std::unique_ptr
    s中(如果
    std::vector
    由于任何原因无法使用)



    或(自C++ 17),您可以分配一个数组:<代码> STD::可选的< /C> >,并考虑“代码> STD::可选的< /COD>空的状态作为默认构造状态的替换。但是我觉得你的老师也不允许这样做。

    你可以使用
    std::vector
    ?你应该在这里使用它。不,我不允许,我的老师要我硬编码。我还没有学过链表,我下学期会学。我非常怀疑你是否需要知道如何在数组中添加非默认可构造类。这不是很直截了当。你告诉我要以某种方式编写代码,但你没有向我解释为什么那样会更好。我想一系列指针对于初学者来说很容易实现,并且可以绕过这个限制。@interjay没有想到这一点。我补充了我的答案。
    varfuri[i] = new Point(/*constructor arguments*/);