c++ - C++ 中的初始化列表和类初始化。我没有参数构造函数,但仍然必须使用初始化列表?

标签 c++ initializer-list

好的 C++ 新手,我非常了解 Java,现在正在尝试学习 C++。 无论如何,这是我的简单类(class)。

class PolyGon{

    private:
        PointArray aArray;
        static int numberOfInst;

    public:
        PolyGon(Point point[], const int newSize) : aArray(point, newSize){} 
};

这很好。如果我错了,请纠正我,但在初始化列表中 aArray(point, newSize) 等同于 aArray = new PointArray(point, newSize)

因为当我尝试完全相同的代码但将最后一行更改为:

class PolyGon{

    private:
        PointArray aArray;
        static int numberOfInst;

    public:
        PolyGon(Point point[], const int newSize){aArray = new PointArray(point, newSize)} 
};

这给出了异常(exception):

no match for 'operator=' in '((PolyGon*)this)->PolyGon::aArray = (((PointArray*)operator new(8u)), (->PointArray::PointArray(((const Point*)point), newSize), ))'|

如果您想在此处查看 PointArray 的构造函数,它是:

PointArray::PointArray(const Point points[], const int newSize)
{
    size = newSize;

    x = new Point[size];

    for(int i = 0; i < size; i++)
    {
        x[i] = points[i];
    }
}

好的,在我提交这个之前,我找到了一个答案,它说如果对象没有默认构造函数,你必须用初始化列表初始化它。我现在有三个问题:

  1. 这是为什么?为什么我不能按照我想要的方式去做。
  2. 这条规则是否只适用于构造函数。就像我可以说“PointArray aArray = new PointArray(point, newSize);”其他地方?
  3. 我确实有一个无参数的构造函数。那么为什么会给我这个错误呢?

我的无参数构造函数如下所示:

PointArray(){size = 0; x = new Point[0];}

最佳答案

Why is this? Why cant I do it the way I wanted to do it.

在 Java 中,aArray 将是对您必须使用 new 创建的单独对象的引用。

在 C++ 中,您必须忘掉您所知道的有关 Java 对象模型的一切。 aArray 是包含在 PolyGon 中的对象,在创建 PolyGon 时自动创建,并在运行构造函数主体之前初始化。如果您需要提供构造函数参数,则必须在构造函数主体之前的初始化列表中给出这些参数;当您进入构造函数主体时,它已经被初始化。

Does this rule only apply to the constructor. Like can I say PointArray aArray = new PointArray(point, newSize); somewhere else?

new 返回指向动态对象的指针;所以你可以用它来初始化一个指针(不是一个对象):

// Careful! This is a recipe for memory leaks.
PointArray * aArray = new PointArray(point, newSize);

但请记住,如果您使用 new 创建了某些内容,则必须在完成后使用 delete 将其销毁。没有垃圾回收,因此被遗弃的动态对象会泄漏内存。为防止这种情况,请尽可能避免 new,并学习如何使用 RAII在您真正需要时管理动态资源。

你也可以在没有new的情况下创建对象:

PointArray aArray(point, newSize);

如果它在代码块内(局部变量;从技术上讲,在 block 作用域),那么当程序离开该 block 时它将自动销毁。如果它不在任何函数内(一个全局变量;从技术上讲,在命名空间范围内),那么它会持续整个程序的持续时间(或多或少);但全局变量通常被认为是一个坏主意。

I do have a no-arg constructor. So why is it giving me this error?

正在使用默认构造函数;但随后您尝试为它分配一个指针。如果你真的想避免初始化列表(你不应该这样做),那么你可以通过复制一个临时的来重新分配给它:

PolyGon(Point point[], const int newSize) {
    aArray = PointArray(point, newSize);  // No new
} 

但这可能效率较低,并且要求该类型实现它可能不需要的默认构造函数和复制赋值运算符。还有一些类型(例如常量和引用)不能默认初始化或重新分配。列表中的直接初始化适用于所有类型。

关于c++ - C++ 中的初始化列表和类初始化。我没有参数构造函数,但仍然必须使用初始化列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18279162/

相关文章:

c++ - 为什么必须复制 std::initializer_list 的元素?

c++ - 在 ";"错误之前继续丢失 "."

c++ - 使用带有继承变量的初始化列表

c++ - 在 C++ 中声明指向结构的指针会自动为其成员分配内存。我错了吗?

c++ - 处理局部引用变量

c++ - 使用转换运算符初始化 map

c++ - 具有多个数组的类的构造函数初始化列表(C++11 可以,boost 和 std::vector 不行)

c++ - 使用一个函数调用 C++ 初始化多个常量类成员

c++ - 在 async_write 挂起时写入 streambuf 是否安全?

c++ - cocos2d-x 每次需要时制作 Sprite 或只是改变其纹理的最佳做法是什么?