Как узнать, статически или динамически размещается объект в конструкторе?

Возможный дубликат:
Обнаружить динамически размещенный объект?

У меня есть объект, который требует немного другой конструкции, независимо от того, является ли его экземпляр статическим или динамическим. Объект должен иметь только один конструктор по умолчанию. Таким образом, не может быть и речи о двух конструкторах, по одному для каждого случая, и о том, что пользователь явно выбирает правильный конструктор.

Есть ли правильный способ добиться этого?

Вот как я делаю это на данный момент: я перегружаю новый оператор для этого объекта, выделяю память и использую возвращенный указатель в качестве указателя на (еще не инициализированный) экземпляр и устанавливаю определенный элемент данных объекта в какое-то магическое значение. Затем в конструкторе я проверяю значение члена. Если это магическое значение, то объект на 99,9% распределяется динамически.

Этот метод еще не подвел меня ни в режимах релиза, ни в режимах отладки, однако он кажется ужасным взломом.


person Community    schedule 18.06.2009    source источник
comment
Нет, ты должен довольствоваться своим взломом. Единственный правильный способ сделать это - исправить свой дизайн.   -  person jalf    schedule 18.06.2009


Ответы (3)


Вы должны быть в состоянии достичь того, чего хотите, оставив один доступный пользователю конструктор по умолчанию (который будет использоваться для статических объектов и auto — похоже, вы игнорируете существование автоматических объектов, например, локальных переменных , поэтому я полагаю, что вы хотите относиться к этим случаям одинаково).

Сделайте operator new и отдельный конструктор как приватными, так и общедоступный статический метод (это случай шаблона проектирования "фабричный метод"), который выполняет только return new TheClass(123); (при условии, что отдельный конструктор принимает, например, целое число, но, конечно, вы можете выбрать любой тип аргумента, который вы хотите, так как аргумент в любом случае не используется).

Вы знаете, что сказали, что у объекта должен быть один конструктор, но с точки зрения пользователя это именно то поведение класса, и нет «явного выбора конструктора» со стороны пользователя (он просто не может вызвать new явно, но должен пройти предоставленный вами заводской метод, вот и все).

person Alex Martelli    schedule 18.06.2009
comment
Я не уверен, что получил это. Вы имеете в виду, что пользователю придется вызывать статическую функцию, чтобы выделить новый экземпляр вместо использования нового? Если это то, что вы имеете в виду, то зачем вообще перегружать new? В любом случае, это не сработает, потому что класс должен быть унаследован, и по вашему методу каждый подкласс также должен определять свою собственную статическую функцию. * Как вы упомянули, автоматические объекты рассматриваются как статические. - person ; 18.06.2009
comment
Создание новых приватных блокирует пользователя от простого вызова new Foo(), как это было бы в противном случае. И да, если все объекты Foo, живущие в динамическом хранилище (включая базовые классы или члены), нуждаются в особом обращении, то мое предложение требует, чтобы другие классы поступали так же, но предложенное вами решение не работает. лучше чем!-) - person Alex Martelli; 19.06.2009

Любой конструктор можно использовать для статического или динамического размещения. У вас нет возможности заставить пользователя объекта использовать конкретный конструктор, каким бы способом он ни выделял объект.

person Dima    schedule 18.06.2009

Я не думаю, что вы можете сказать в конструкторе.

Я не знаю, поможет ли это, но вы можете предотвратить статическое создание объекта, сделав деструктор закрытым. Вам также потребуется общедоступный метод «Удалить», который выполняет delete this для кода, который динамически выделяет объекты этого класса — им придется выполнять obj->Delete(), а не delete obj.

person Graeme Perrow    schedule 18.06.2009
comment
Это вообще не работает в базовом классе. Частный деструктор предотвратит существование объекта подкласса. Деструктор защищенного базового класса может быть вызван из его дочерних элементов, что означает, что подкласс может быть создан в стеке. Если подкласс также не ограничивает видимость его dtor. В любом случае защищенный dtor для базового класса бесполезен. - person Mark Borgerding; 23.06.2009