nmyers@mntgfx.mentor.com (Nathan Myers) (06/08/89)
Providing arguments for operators new() and delete() is a major advance. It offers more power than "this=" semantics, and allows smaller, faster code. However, ark@alice.UUCP (Andrew Koenig) writes > Operator new (and operator delete) obeys the same scope rules as any > other member function: if defined inside a class, operator new hides > any global operator new. For example: > > class T { > /* stuff */ > public: > void* operator new(size_t, Memory_speed); > /* more stuff */ > }; > > T* tp = new T; // Error! > > The use of `new T' is incorrect in this example because the member > operator new hides the global operator new, so no operator new > can be found for T that does not require a second argument. This seems inconsistent to me. Other overloaded functions don't hide their neighbors, why should operator new()? The standard way to hide a global is to declare a member with the same name and arguments. Then, if I (as class T author) want to disallow ::operator new(size_t), I can declare a private one and not define it. A self-consistent alternative to the posted semantics is: 1. Member operator new(size_t, class Foo) doesn't hide global ::new(size_t). 2. Member operator new(size_t) may be declared private. 3. "::new T" is not valid syntax. (It seems unnecessary, and dangerous.) Nathan Myers nmyers@pdx.mentor.com
rfg@pink.ACA.MCC.COM (Ron Guilmette) (06/10/89)
In article <1989Jun7.115321.22620@mntgfx.mentor.com> nmyers@mntgfx.mentor.com (Nathan Myers) writes:
^ >Providing arguments for operators new() and delete() is a major
^ >advance. It offers more power than "this=" semantics, and allows
^ >smaller, faster code. However,
... [ problems ] ...
^ >This seems inconsistent to me. Other overloaded functions don't
^ >hide their neighbors, why should operator new()? The standard way
^ >to hide a global is to declare a member with the same name and arguments.
^ >Then, if I (as class T author) want to disallow ::operator new(size_t),
^ >I can declare a private one and not define it.
^ >
^ >A self-consistent alternative to the posted semantics is:
^ >1. Member operator new(size_t, class Foo) doesn't hide global ::new(size_t).
^^^^^^^^^^^^^
Do you mean ::operator new(size_t) ?
^ >2. Member operator new(size_t) may be declared private.
^ >3. "::new T" is not valid syntax. (It seems unnecessary, and dangerous.)
^^^^^^^^
Did you mean ::operator new T ?
--
// Ron Guilmette - MCC - Experimental Systems Kit Project
// 3500 West Balcones Center Drive, Austin, TX 78759 - (512)338-3740
// ARPA: rfg@mcc.com
// UUCP: {rutgers,uunet,gatech,ames,pyramid}!cs.utexas.edu!pp!rfg
ark@alice.UUCP (Andrew Koenig) (06/10/89)
In article <242@pink.ACA.MCC.COM>, rfg@pink.ACA.MCC.COM (Ron Guilmette) writes: > In article <1989Jun7.115321.22620@mntgfx.mentor.com> nmyers@mntgfx.mentor.com (Nathan Myers) writes: > ^ >A self-consistent alternative to the posted semantics is: > ^ >1. Member operator new(size_t, class Foo) doesn't hide global ::new(size_t). > ^^^^^^^^^^^^^ > > Do you mean ::operator new(size_t) ? > > ^ >2. Member operator new(size_t) may be declared private. > ^ >3. "::new T" is not valid syntax. (It seems unnecessary, and dangerous.) > ^^^^^^^^ > > Did you mean ::operator new T ? I guess it's time for me to jump in again. An example: class T { public: void* operator new(size_t); void operator delete(); // other stuff }; void f() { T* tp1 = new T; // calls T::operator new T* tp2 = ::new T; // calls ::operator new T* tp3 = T[10]; // calls ::operator new delete tp1; // calls T::operator delete ::delete tp2; // calls ::operator delete delete[10] tp3; // calls ::operator delete } When you say `new T' it looks for `operator new' using the usual scope rules as if you were in the definition of a member function of T. That is: it first looks for T::operator new, then it searches the base class(es) of T, and finally it looks in the global scope. When you say `::new T' it skips T and all its base classes and goes straight to the global scope. Most people will never use ::new or ::delete; that's why they have a funny kind of syntax. They are there to help authors of container classes. For example, suppose you're writing an array-like class that will contain objects of arbitrary type. Once C++ gets templates, that will be easy, but even now it can be done reasonably effectively through the C preprocessor. Now, suppose you've written a class T and I want to make a container that contains T objects? My container had better control the memory allocation for the objects it contains, so that it can free the objects when the container itself is freed. But how can the container control memory allocation for T if T itself controls its memory allocation? Evidently we need a mechnism for overriding a class' request to control its own memory. That is the purpose of ::new and ::delete. -- --Andrew Koenig ark@europa.att.com
shopiro@alice.UUCP (Jonathan Shopiro) (06/14/89)
In article <1989Jun7.115321.22620@mntgfx.mentor.com>, nmyers@mntgfx.mentor.com (Nathan Myers) writes: > Providing arguments for operators new() and delete() is a major > advance. It offers more power than "this=" semantics, and allows > smaller, faster code. However, > > ark@alice.UUCP (Andrew Koenig) writes > > Operator new (and operator delete) obeys the same scope rules as any > > other member function: if defined inside a class, operator new hides > > any global operator new. For example: > > > > class T { > > /* stuff */ > > public: > > void* operator new(size_t, Memory_speed); > > /* more stuff */ > > }; > > > > T* tp = new T; // Error! > > > > The use of `new T' is incorrect in this example because the member > > operator new hides the global operator new, so no operator new > > can be found for T that does not require a second argument. > > This seems inconsistent to me. Other overloaded functions don't > hide their neighbors, why should operator new()? The standard way > to hide a global is to declare a member with the same name and arguments. > Then, if I (as class T author) want to disallow ::operator new(size_t), > I can declare a private one and not define it. No. If the name is the same, the function is hidden. For example: void foo(int); struct S { void foo(); void bar(); }; void S::bar() { foo(1); // error: unexpected 1 argument for S::foo() } m o r e s i l l i n e s s -- Jonathan Shopiro AT&T Bell Laboratories, Warren, NJ 07060-0908 research!shopiro (201) 580-4229
kc@rna.UUCP (Kaare Christian) (05/12/91)
I haven't noticed any discussion of the following contradiction in the ARM: In 5.3.3 there is a mention that operator new can be called with argument 0, in which case it must return a pointer to an object. In 12.5 it states that if operator new is called with argument 0, it must return 0. Also, the ARM defines a *nested* class as a class defined inside another class, while a *local* class is a class defined inside a function. It then defines a *local* type as a type defined inside a class. Shouldn't we call 'em **nested** types? Kaare Christian kc@rna.rockefeller.edu
comeau@ditka.Chicago.COM (Greg Comeau) (05/16/91)
In article <1107@rna.UUCP> kc@rna.UUCP (Kaare Christian) writes: >I haven't noticed any discussion of the following contradiction in the ARM: >In 5.3.3 there is a mention that operator new can be called with argument 0, >in which case it must return a pointer to an object. >In 12.5 it states that if operator new is called with argument 0, it must >return 0. I had brought this issue up on BIX quite a while back. 12.5 is wrong. >Also, the ARM defines a *nested* class as a class defined inside another >class, while a *local* class is a class defined inside a function. It then >defines a *local* type as a type defined inside a class. Shouldn't we >call 'em **nested** types? It should be local... as is. The first line of 9.9 says it all to me: "Type names obey exactly the same scope rules as other names." "local" is a C++ scope. - Greg -- Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418 Producers of Comeau C++ 2.1 Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421 Voice:718-945-0009 / Fax:718-441-2310