Вопрос 1:
Ваше определение
void* operator new(size_t count, const std::string t_name, const size_t dat) //...
в Watchdog.cxx
определяет свободную пользовательскую operator new
, а не перегрузку, специфичную для класса, которую вы объявили в классеWatchdog
.
Вместо этого используйте:
void* Watchdog::operator new(size_t count, const std::string t_name, const size_t dat) //...
Поскольку для new-expression в main
выбрано переопределение класса, его определение будетотсутствует.
Вопрос 2:
operator new
возвращает только указатель на необработанную память. Он не отвечает за конструирование объектов в нем.
Объекты создаются с помощью new-expression с вызовом конструктора по мере необходимости. Синтаксис соответствует синтаксису определений переменных. Например,
W = new ("test", 20) Watchdog;
вызывает конструктор по умолчанию для объекта Watchdog
, а
W = new ("test", 20) Watchdog(arg1, arg2, arg3);
попытается вызвать перегрузку конструктора, соответствующую трем аргументам.
Первый список параметров в new-expression используется не в качестве аргументов для конструктора, а в качестве аргументов, необходимых для функции выделения, чтобы обеспечить правильный указатель на память, в которой может быть построен объект.
Также обратите внимание, что operator new
должен выделять память для (как минимум) count
(первый аргумент) байтов. Для этого аргумента будет указано правильное значение, необходимое для создания объекта, с помощью new-expression . Это особенно важно, когда вы используете версии массивов operator new
и new
.
Также имейте в виду, что вы создаете только сам объект Watchdog
в общей памяти, предоставляемой вашей перегрузкой operator new
. Если ваш класс использует new
для выделения памяти, например, для члена void* m_data
, он будет использовать не operator new
для выделения, а обычную функцию выделения, которая будет выделять (как обычно) в памяти процессов (неразделенной)пробел.
То же самое относится к памяти, выделенной нетривиальным членам вашего класса, таким как std::string m_name
. Когда ему понадобится выделить память (если SSO недостаточно), он выделит память для строковых данных с помощью обычной функции выделения (в неразделенной памяти), а не вашей перегрузки operator new
.
Этоозначает, например, что m_name
нельзя безопасно использовать из другого процесса, с которым вы делитесь памятью.