C++中新的使用

C++中新的使用,c++,C++,假设我将一个新对象传递给如下函数: loadContainer->addControlView( new BmpView( BMP_PICTURE ) ); Control* newView = new BmpView( BMP_PICTURE ); newView->changeColor( WHITE ); loadContainer->addControlView( newView ); 现在,我想在将BmpView传递给addControlView之前更改它的一个特

假设我将一个新对象传递给如下函数:

loadContainer->addControlView( new BmpView( BMP_PICTURE ) );
Control* newView = new BmpView( BMP_PICTURE );
newView->changeColor( WHITE );
loadContainer->addControlView( newView );
现在,我想在将BmpView传递给addControlView之前更改它的一个特定特性。我是这样做的:

loadContainer->addControlView( new BmpView( BMP_PICTURE ) );
Control* newView = new BmpView( BMP_PICTURE );
newView->changeColor( WHITE );
loadContainer->addControlView( newView );

这是否会创建额外的临时/本地对象?或者在这两种情况下分配的内存量相等吗?

函数中唯一添加的内存是一个新指针*newView,它的大小非常小,不受BmpView实际大小的影响。它不会为BmpView分配两次内存


我没有考虑调用changeColor的任何内存开销,我认为这不是问题的重点。

函数中唯一添加的内存是一个新指针*newView,它的大小非常小,不受BmpView实际大小的影响。它不会为BmpView分配两次内存


我没有考虑调用changeColor的任何内存开销,我认为这不是问题的重点。

在这两种情况下,都有一个对new的调用,因此使用的内存量是相等的。注意,这并不是猜测BmpView构造函数、changeColor等可能请求的任何分配

但是,您可能希望重构代码以确保某些异常安全性,避免潜在的泄漏,从而确保使用的内存量得到控制:

// C++11
std::unique_ptr<Control> newView(new BmpView(BMP_PICTURE));
// C++14, preferred
//auto newView = std::make_unique<BmpView>(BMP_PICTURE);
newView->changeColor( WHITE );
loadContainer->addControlView( newView.release() );

在这两种情况下,都有一个对new的调用,因此使用的内存量是相等的。注意,这并不是猜测BmpView构造函数、changeColor等可能请求的任何分配

但是,您可能希望重构代码以确保某些异常安全性,避免潜在的泄漏,从而确保使用的内存量得到控制:

// C++11
std::unique_ptr<Control> newView(new BmpView(BMP_PICTURE));
// C++14, preferred
//auto newView = std::make_unique<BmpView>(BMP_PICTURE);
newView->changeColor( WHITE );
loadContainer->addControlView( newView.release() );

以下代码/组件的参考:

示例中,您创建一个包含指针的局部变量,对其执行某些操作,然后将其传递给函数

main:
        push    rbp
        mov     rbp, rsp
        mov     edi, 4
        call    operator new(unsigned long)
        mov     DWORD PTR [rax], 0
        mov     rdi, rax
        call    PrintValueClass(ValueClass*)
        mov     eax, 1
        pop     rbp
        ret
 main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     edi, 4
        call    operator new(unsigned long)
        mov     DWORD PTR [rax], 0
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        mov     DWORD PTR [rax], 55
        mov     rax, QWORD PTR [rbp-8]
        mov     rdi, rax
        call    PrintValueClass(ValueClass*)
        mov     eax, 1
        leave
        ret
在进入程序集之前,如果您的问题是如果您首先将指针存储在变量中,新操作是否会发生两次,答案是否。如程序集所示,新的“函数”只调用一次,因此只有sizeofValueClass会在这里通过某种堆分配函数进行分配。但我觉得有必要充分回答这个问题,即使它并不是有意提出这个问题。是否使用了额外的内存?技术上是的,实际上不是

这两段代码之间的唯一区别是堆栈“分配”,由子rsp 16表示,这本质上意味着为局部变量在堆栈上“分配”16个字节。所以这里唯一的区别是16个字节,这将极大地改变您使用的编译器、目标体系结构以及更多因素


最后,我想说的是,您永远不会关心额外的16个字节。

以下代码/程序集的参考:

示例中,您创建一个包含指针的局部变量,对其执行某些操作,然后将其传递给函数

main:
        push    rbp
        mov     rbp, rsp
        mov     edi, 4
        call    operator new(unsigned long)
        mov     DWORD PTR [rax], 0
        mov     rdi, rax
        call    PrintValueClass(ValueClass*)
        mov     eax, 1
        pop     rbp
        ret
 main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     edi, 4
        call    operator new(unsigned long)
        mov     DWORD PTR [rax], 0
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        mov     DWORD PTR [rax], 55
        mov     rax, QWORD PTR [rbp-8]
        mov     rdi, rax
        call    PrintValueClass(ValueClass*)
        mov     eax, 1
        leave
        ret
在进入程序集之前,如果您的问题是如果您首先将指针存储在变量中,新操作是否会发生两次,答案是否。如程序集所示,新的“函数”只调用一次,因此只有sizeofValueClass会在这里通过某种堆分配函数进行分配。但我觉得有必要充分回答这个问题,即使它并不是有意提出这个问题。是否使用了额外的内存?技术上是的,实际上不是

这两段代码之间的唯一区别是堆栈“分配”,由子rsp 16表示,这本质上意味着为局部变量在堆栈上“分配”16个字节。所以这里唯一的区别是16个字节,这将极大地改变您使用的编译器、目标体系结构以及更多因素


最后,我想说的是,你永远不会关心额外的16个字节。

取决于changeColor返回的内容。changeColor是一个空白。简短回答:是的,除非changeColor分配内存,否则它使用相同的内存量,但它仍然在BmpView对象内。您可以使用valgrind之类的工具来确定是否存在内存泄漏。这取决于changeColor返回的内容。changeColor是一个空值。简短回答:是的,除非changeColor分配内存,否则这将使用相同的内存量,但它仍将位于BmpView对象内部。您可以使用valgrind之类的工具来查明是否存在内存泄漏。