|
|
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Привет всем ! Вопрос такой . В конструкторе надо узнать использовался ли new при создании . Тое Foo bar; или Foo * bar= new Foo() У Страуструпа написано смотри на this указатель . Если this = 0 то первый вариант на самом деле при написании проги на Visual C++ 6.0 VS2005 Builder программа #include <iostream> class Foo { public : Foo() { if (this) cout << "B"; else cout <<"A" } }; int main () { Foo x; Foo * y = new Foo (); return 0; } результат BB всегда ! Что делать собственно ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2006, 16:51 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Мона попробовать Foo *x=NULL; Или сравнить адрес &x с адресом стека (это изврат ИМХО кому это надо?). Или посмотреть опции компиллера. P.S. Или я чет не понял. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2006, 17:10 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Не передавать именно надо Foo x; или Foo * x = new Foo() а парится в конструкторе на самом деле простои интересно стало кому верить ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2006, 17:22 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
авторУ Страуструпа написано смотри на this указатель Самому мне что-то не найти... тоже интересно... Можно точную цитату? Да я как-то у тов-ща о чем-то похожем спрашивал... В этот момент мой рейтинг упал ниже плинтуса :) Зачем если не секрет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2006, 18:41 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
http://www.unix.org.ua/cpp/gl5_2.htm 5.5.7 .... Конструктор может определить, был ли он вызван операцией new, или нет. Если он вызван new, то указатель this на входе имеет нулевое значение, в противном случае this указывает на пространство, уже выделенное для объекта (например, на стек). Поэтому можно просто написать конструктор, который выделяет память, если (и только если) он был вызван через new. Например: mytype::mytype(int i) { if (this == 0) this = mytype_alloc(); // присваивание членам }; Эквивалентного средства, которое позволяет деструктору решить вопрос, был ли его объект создан с помощью new, не имеется, как нет и средства, позволяющего ему узнать, вызвала ли его delete, или он вызван объектом, выходящим из области видимости. Если для пользователя это существенно, то он может сохранить где-то соответствующую информацию для деструктора. Другой способ, - когда пользователь обеспечивает, что объекты этого класса размещаются только соответствующим образом. Если удается справиться с первой проблемой, то второй способ интереса не представляет. Если тот, кто реализует класс, является одновременно и его единственным пользователем, то имеет смысл упростить, исходя из предположений о его использовании. Когда класс разрабатывается для более широкого использования, таких допущений, как правило, лучше избегать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2006, 19:47 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Да... забавно... всётаки это наверное зависит и от компилятора... Хотя и похоже на бред... это бред... т.е. в 80% эта возможность ни кому не нужна... (это рассуждения делетанта коим я являюсь) Спасибо за цитату. :) Ради праздного любопытства взгляните, что написано в MSDN про this. Т.е. объект уже размещён в памяти (см. реализацию new) и хитрый компилятор пихает этот адрес как скрытый аргумент в вызов любой функции... Хорошая тема для обсуждения... Наверное адепты наставят меня на путь истиный... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.03.2006, 23:42 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
cap83В конструкторе надо узнать использовался ли new при создании . Это невозможно. Если у тебя написано в книге Страуструпа (или еще где) проверять this, то книга устаревшая и это давно уже неправда, потому что это понятия до стандарта C++. Единственный вариант в классе определить динамически выделен объект или нет, это вести пул всех созданных динамически объектов. 1) Заводится статический массив, который содержит список адресов всех объектов данного класса, созданных динамичеки. 2) Переопределяется в данном классе operator new. 3) в operator new каждый созданный экземпляр заносится в этот список динамически созданных объектов 4) В конструкторе можно проверить, содержится ли конструируемый экземпляр в списке динамически выделенных экземпляров. 5) Надо учитывать особенности переопределения operator new и особенности работы в многопоточной среде (если это нужно), поскольку у вас будут статические данные -- при необходимости их нужно защищать мьютексами или семафорами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 01:00 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
cap83Если он вызван new, то указатель this на входе имеет нулевое значение, в противном случае this указывает на пространство, уже выделенное для объекта (например, на стек). Поэтому можно просто написать конструктор, который выделяет память, если (и только если) он был вызван через new. Это - еще раз, цитаты из какого-то фуфла из эпохи до стандартизации. Да, тогда были подобного рода изыски. Но это было в годах примерно 1987 В современном С++ (XXI века) 1) this в конструкторе всегда отличен от нуля и содержит адрес уже выделенного (но возможно еще неполностью сконструированного) объекта. 2) this неявно объявляется как T * const, во всех методах, в том числе и в конструкторе и деструкторе, т.е. указателю НЕЛЬЗЯ ПРИСВОИТЬ НОВОЕ ЗНАЧЕНИЕ (нельзя перенести объект в другой адрес). 3) Невозможно определить в конструкторе и деструкторе способ выделения памяти под объект. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 01:07 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Ну собственно - что и требовалось доказать... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 09:12 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
У Мейерса в More Effective C++ есть способ решения этой проблемы. Книжки под рукой нет, но в И-Нете можно поискать. Проблема обсосана многопланово - как запретить создание объекта в куче, как запретить создание объекта везде, кроме кучи и как определить, где создан объект - в стат.памяти, в куче или в стеке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 15:36 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
У Меерса и написано то, о чем написал я. Ну плюс конечно много всяческих подробностей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 16:44 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Doc No: N1905=05-0165 Date: 2005-10-19 Reply to: Pete Becker Dinkumware, Ltd. petebecker@acm.org Working Draft, Standard for Programming Language C++ Цитата: A pointer to objects of type T is referred to as a "pointer to T." [ Example: a pointer to an object of type int is referred to as "pointer to int " and a pointer to an object of class X is called a "pointer to X." -end example ] Except for pointers to static members, text referring to "pointers" does not apply to pointers to members. Pointers to incomplete types are allowed although there are restrictions on what can be done with them (3.9). A valid value of an object pointer type represents either the address of a byte in memory (1.7) or a null pointer (4.10). If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained. [ Note: for instance, the address one past the end of an array (5.7) would be considered to point to an unrelated object of the array's element type that might be located at that address. -end note ] The value representation of pointer types is implementation-defined. Pointers to cv-qualified and cv-unqualified versions (3.9.3) of layout-compatible types shall have the same value representation and alignment requirements (3.9). Про это разговор? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 17:37 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
void * operator new(std :: size_t size , const std :: nothrow_t &) throw (); 5 Effects: Same as above, except that it is called by a placement version of a new-expression when a C++ program prefers a null pointer result as an error indication, instead of a bad_alloc exception. 6 Replaceable: a C++ program may define a function with this function signature that displaces the default version defined by the C++ Standard library. 7 Required behavior: Return a non-null pointer to suitably aligned storage (3.7.3), or else return a null pointer. This nothrow version of operator new returns a pointer obtained as if acquired from the ordinary version. This requirement is binding on a replacement version of this function. 8 Default behavior: — Executes a loop: Within the loop, the function first attempts to allocate the requested storage. Whether the attempt involves a call to the Standard C library function malloc is unspecified. — Returns a pointer to the allocated storage if the attempt is successful. Otherwise, if the last argument to set_new_handler() was a null pointer, return a null pointer. — Otherwise, the function calls the current new_handler (18.4.2.2). If the called function returns, the loop repeats. — The loop terminates when an attempt to allocate the requested storage is successful or when a called new_-handler function does not return. If the called new_handler function terminates by throwing a bad_alloc exception, the function returns a null pointer. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 17:54 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
MasterZiv У Меерса и написано то, о чем написал я. Ну плюс конечно много всяческих подробностей. Есть дополнение по поводу подробностей MasterZiv 1) Заводится статический массив, который содержит список адресов всех объектов данного класса, созданных динамичеки. нужно позаботиться о поведении конструкторов копирования. Очень злую шутку они могут сыграть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 20:53 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
авторЭто - еще раз, цитаты из какого-то фуфла из эпохи до стандартизации. Да, тогда были подобного рода изыски. Но это было в годах примерно 1987 Не в курсах что C++ Бьярн Страустрап придумал ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 21:10 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
onstat- MasterZiv 1) Заводится статический массив, который содержит список адресов всех объектов данного класса, созданных динамичеки. нужно позаботиться о поведении конструкторов копирования. Очень злую шутку они могут сыграть. А там конструкторы и не используются. Там используется абстрактный mixin класс, у которого перегружены operator new и operator delete. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.03.2006, 23:54 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Не поленился и глянул в Майерса. Если отбросить детали, сказано, что объект не может сколь нибудь переносимым и надежным образом определить создается ли он в хипе или на стеке. 2 Сергей Ильич Возможно в книжках нужно читать не только заголовки ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 09:04 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Gluk (Kazan)Не поленился и глянул в Майерса. Если отбросить детали, сказано, что объект не может сколь нибудь переносимым и надежным образом определить создается ли он в хипе или на стеке. Вранье. Там написано, как определять, факт существования объекта на хипе или в стеке (приведен абстрактный класс HeapTracked). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 12:52 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Процитируйте если не затруднит. Просто интересно, что из написанного Вы имеете в виду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 14:22 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Fortunately, C++ gives us exactly what we need in the form of an abstract mixin base class. ¤ Item M27, P48 An abstract base class is a base class that can't be instantiated, i.e., one with at least one pure virtual function. A mixin ("mix in") class is one that provides a single well-defined capability and is designed to be compatible with any other capabilities an inheriting class might provide (see Item E7). Such classes are nearly always abstract. We can therefore come up with an abstract mixin base class that offers derived classes the ability to determine whether a pointer was allocated from operator new. Here's such a class: ¤ Item M27, P49 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Implementation of the HeapTracked class is simple, because the global operator new and operator delete functions are called to perform the real memory allocation and deallocation, and the list class has functions to make insertion, removal, and lookup single-statement operations. Here's the full implementation of HeapTracked: ¤ Item M27, P51 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. The only other thing that may confound you is this statement (in isOnHeap): ¤ Item M27, P53 Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 15:19 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Мдя... Наверное круто... Писать чтонить такое, где подобные "извраты" могут пригодиться (завидую)... Вышеизложенный вариант решения очевиден... Но цитата мене убила (if (this == 0) this = mytype_alloc();). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.03.2006, 18:13 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Сергей ИльичFortunately, C++ gives us exactly what we need in the form of an abstract mixin base class. ¤ Item M27, P48 ... Два возражения к приведенному коду: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Цитируемый код не предназначен для определения того, находится ли объект в хипе (это невозможно), он всего лишь позволяет проверить можно ли применять delete. Согласитесь, это не одно и то-же. Вот что пишет по этому вопросу Майерс парой абзацев выше: автор The sad fact is there's not only no portable way to determine whether an object is on the heap, there isn't even a semi-portable way that works most of the time. If you absolutely, positively have to tell whether an address is on the heap, you're going to have to turn to unportable, implementation-dependent system calls, and that's that. As such, you're better off trying to redesign your software so you don't need to determine whether an object is on the heap in the first place. ¤ Item M27, P40 ... As luck would have it, it's easier to determine whether it's safe to delete a pointer than to determine whether a pointer points to something on the heap, because all we need to answer the former question is a collection of addresses that have been returned by operator new. Since we can write operator new ourselves (see Items E8-E10), it's easy to construct such a collection. Here's how we might approach the problem: ¤ Item M27, P43 Вопросы, предложения, пожертвования ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 07:56 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Не понял замечанеие 2. Хочешь сказать, эти опреаторы не наследуются? Мой компилятор их, однако, наследует: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. Output: Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 13:59 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Sorry, конечно я имел в виду другое Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. VMT тоже могут дать жизни в плане совместимости. По массиву вопросов нет ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 14:13 |
|
||
|
Узнать в конструкторе использовался ли new при создании
|
|||
|---|---|---|---|
|
#18+
Вопрос этот философский. Вообще говоря, объект A находится не в куче, а вложен в другой объект - это можно рассматривать как отдельный тип стораджа. Что касается массивов, то можно перегрузить operator new[] - там размер массива известен, следовательно можно зарегистрировать сразу все объекты в той же самой таблице. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.03.2006, 14:48 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=33630569&tid=2031652]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
165ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
44ms |
get tp. blocked users: |
1ms |
| others: | 203ms |
| total: | 456ms |

| 0 / 0 |
