繁体   English   中英

C ++:运算符new和default构造函数

[英]C++ : operator new and default constructor

我在理解如何与构造函数一起使用动态分配时遇到了麻烦。

我在我的代码中使用了一个名为graph的类(它只是表示节点之间边缘的bool 2-d矩阵),并带有以下构造函数/析构函数(还有其他方法,但我认为在这里不相关):

class graph{

private:
bool** edges;
int size;

public:
graph(int size = 0):size(size){
    edges = new bool*[size];
    for (int i = 0; i < size; i++){
        edges[i] = new bool[size];
    }
}

~graph(){
    for(int i = 0; i < size; ++i) {
        delete [] edges[i];
    }
    delete [] edges;
}

//others methods

};

我主要要使用动态分配:

int main()
{

    int size;
    cout << "Enter graph size :" << endl;
    cin >> size;

    graph g1 = new graph(size);

    //some processing code

    return 0;
}

Howewer,我在实例化时出错(即new graph(size)):

从'graph *'到'int'的无效转换[-fpermissive]

我并没有真正弄明白问题出在哪里,而且我很确定这是我在其他地方已经看到的语法。

实际上,我并不真正了解内存分配如何与对象的创建一起工作。

在这里,我在构造函数中使用new来创建bool 2d-matrix,所以它会进入堆,不是吗? 但是,如果我使用以下静态指令实例化该对象:graph g1(const_size);

那不是应该去栈吗?

预先感谢您的回答。

编辑

最后一个问题:

图形* g1 =新图形(大小);

将g1(指针)存储在堆栈上,但是对象是在堆上创建的。

图g1(size);

在堆栈上创建对象,而g1是对其的引用。

但是无论如何,矩阵的边缘会在堆上? 或者在第二种情况下,它将以某种方式结束堆栈?

错误在这里:

graph g1 = new graph(size);

应该是:

graph *g1 = new graph(size);

原因如下:

new graph(size)

正在创建新的graph对象,并返回指向它的指针(具有graph*类型),并且:

graph g1 = ... 

正在尝试将该对象转换为int (以便调用graph(int)构造函数)-因此错误是invalid conversion from 'graph*' to 'int'

现在,我想这是某种练习,因为在此示例中您不应该在堆上使用分配。 但是,无论如何,请不要忘记:

delete g1;

实际上,我并不真正了解内存分配如何与对象的创建一起工作。

graph *g1 = new graph(size);

g1 (指针)存储在堆栈上,但是对象是在堆上创建的。

graph g1(size);

在堆栈上创建对象,而g1是对其的引用。

PS避免这种情况:

 graph g1 = graph(const_size);

这将首先在语句的右侧创建评估,并将临时graph对象,并将使用copy-constructor初始化g1

但是,例如,如果我想要一个可以处理各种图形大小的程序,而不必每次使用不同大小的图形时都进行重新编译,那么我将需要类似的东西,不是吗?

不,您可以为此使用堆栈分配(我刚刚注意到,在您的示例中,您使用的是const_size-分配给堆栈的对象的构造函数的参数不需要恒定):

int size;
std::cout << "Enter size: ";
std::cin >> size;
graph g1(size);

是的,这里不需要动态分配,我只是编写了代码来练习自己。 但是如果我想在不重新编译的情况下使用各种大小的图形,这将是必要的,不是吗?

不,请看此上方的示例-堆栈分配的对象,其大小可变-无需重新编译。

我以为我们不应该自己调用析构函数,而超出范围时无论如何都要调用它? (我什至读到在某些情况下调用它实际上是不好的,因为它可能是第二次调用它)

对于堆栈分配的对象,这是正确的-析构函数将在作用域的末尾被调用。 但是,如果在堆上分配对象,则在调用delete之前不会调用析构函数。

但是无论如何,矩阵的边缘会在堆上?

    edges = new bool*[size];
    for (int i = 0; i < size; i++){
        edges[i] = new bool[size];
    }

是的,整个矩阵都分配在堆上。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM