Как часть стратегии оптимизации, я хотел бы «притвориться», что я фактически выделяю объект в куче, тогда как на самом деле я просто использовал бы ранее существующий объект, не обращая внимания на остальную часть приложения, потому чтопроверка возвращаемого адреса не выполняется, и к полям из объектов никогда не будет обращаться. Кроме того, конструктор класса не имеет побочных эффектов.
Поэтому я хотел бы знать, демонстрирует ли следующая программа поведение, которое четко определено, зависит от реализации, не определено или недопустимо в целом, словомстандарт.
#include <memory>
#include <cassert>
class Base {
public:
Base(){}
virtual ~Base(){}
};
class Derived: public Base {
public:
using Base::Base;
static void *operator new(std::size_t s) {
static void *mem = ::operator new(s);
return mem;
}
static void operator delete(void *mem) {
/* no-op */
}
};
int main() {
using Ptr = std::unique_ptr<Base>;
Ptr p1 { new Derived };
Ptr p2 { new Derived };
Ptr p3 { new Derived };
Ptr p4 { new Derived };
// assert just in this test, not in the real program
assert(p1 == p2 && p2 == p3 && p3 == p4);
return 0;
}
Чтение §6.7.2.9 текущего рабочего проекта C ++ ( N4835 ) кажется недопустимым:
Два объекта с перекрывающимися временами жизникоторые не являются битовыми полями, могут иметь один и тот же адрес, если одно вложено в другое, или если хотя бы один является подобъектом нулевого размера, и они имеют разные типы; в противном случае они имеют разные адреса и занимают непересекающиеся байты памяти ²⁹.
Однако примечание 29, на которое ссылается вышеприведенный абзац, гласит:
В соответствии с правилом «как если бы» реализации разрешено хранить два объекта с одинаковым машинным адресом или вообще не сохранять объект , если программа не может наблюдать разницу .
Как указывалось в начале, в моем случае программе было наплевать на адрес, по которому размещен этот объект, все, что требуется, - это то, что он может быть выделен с помощью operator new
. и избавился от operator delete
, так что, похоже, он соответствует требованиям, указанным в примечании 29. Это правильно?