Как работает новый оператор, перегруженный в этом примере, без передачи объема памяти, который будет выделен? - PullRequest
0 голосов
/ 13 сентября 2018

В приведенном ниже примере, взятом из https://docs.microsoft.com/en-in/cpp/cpp/new-and-delete-operators?view=vs-2017, как новый оператор узнает значение stAllocateBlock, когда оно никогда не передается в вызове:

Blanks *a5 = new(0xa5) Blanks; 

И что является фактическимреализация operator new в глобальном масштабе.Как он вызывает конструктор конкретного создаваемого объекта и какие параметры он принимает.

// spec1_the_operator_new_function1.cpp  
#include <malloc.h>  
#include <memory.h>  

class Blanks  
{  
public:  
    Blanks(){}  
    void *operator new( size_t stAllocateBlock, char chInit );  
};  
void *Blanks::operator new( size_t stAllocateBlock, char chInit )  
{  
    void *pvTemp = malloc( stAllocateBlock );  
    if( pvTemp != 0 )  
        memset( pvTemp, chInit, stAllocateBlock );  
    return pvTemp;  
}  
// For discrete objects of type Blanks, the global operator new function  
// is hidden. Therefore, the following code allocates an object of type  
// Blanks and initializes it to 0xa5  
int main()  
{  
   Blanks *a5 = new(0xa5) Blanks;  
   return a5 != 0;  
} 

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Вы называете тип Blanks в new(0xa5) Blanks. Для реализации несложно передать хотя бы sizeof(Blanks) автоматически. На самом деле, это именно то, что он делает.

Именно поэтому перегруженный operator new корректно работает с производными классами. Например:

struct D : Blanks { char dummy[2]; }; 

Если бы вы сделали new(0xa5) D, то реализация прошла бы sizeof(D), потому что это самый производный тип класса, который статически появляется в новом выражении.

0 голосов
/ 13 сентября 2018

В отличие от других операторов, где выражение, включающее этот оператор, эффективно отображается непосредственно на соответствующий вызов функции operator, new-expression - это больше, чем просто один способ вызова operator new функция. Цель new-expression - создать объект некоторого типа. Существует нечто большее, чем создание объекта какого-либо типа, чем просто решить, в какой части памяти этот объект должен жить. Например, могут потребоваться вызовы конструкторов. new-expression может использовать функцию выделения (то есть функцию operator new) для выделения памяти. Но не каждый new-expression обязательно должен вызывать функцию выделения. В некоторых ситуациях компилятору разрешено пропускать вызовы функций распределения, например объединять несколько распределений в одно. Таким образом, в конце концов, компилятор решает, когда выделять память для чего. Он вызывает функцию operator new для обработки фактического выделения памяти. И когда он это делает, он знает, сколько памяти запрашивать, основываясь на том, какие объекты будут созданы в этом хранилище. И этот размер запроса будет передан в качестве первого аргумента функции operator new. Этот первый аргумент всегда присутствует, то, что вы пишете в скобках после new в new-expression , будет просто передаваться в качестве аргументов в дополнение к неявному первому ...

0 голосов
/ 13 сентября 2018

Рассчитывается от размера объекта, который будет выделен.В выражении

Blanks *a5 = new(0xa5) Blanks; 

stAllocateBlock будет sizeof(Blanks)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...