What is an Anonymous Object?
The C++ standard does not define the term "anonymous object", but it stands to reason that one might sanely use the term to describe any object that has no name:
- Temporaries:
f(T());
- Unnamed function parameters:
void func(int, int, int);
What I wouldn't count is dynamically-allocated objects:
Technically speaking, an "object" is any region of storage [1.8/1 in 2003], which would include the X bytes making up the integer dynamically-allocated by new int;
.
In int* ptr = new int;
the pointer (itself an object too, don't forget!) has the name ptr
and the integer itself has no name other than *ptr
. Still, I'd hesitate to call this an anonymous object.
Again, though, there's no standard terminology.
Scope of methods of an anonymous object - Kotlin
From docs Object Expressions and Declarations:
Note that anonymous objects can be used as types only in local and
private declarations. If you use an anonymous object as a return type
of a public function or the type of a public property, the actual type
of that function or property will be the declared supertype of the
anonymous object, orAny
if you didn't declare any supertype. Members
added in the anonymous object will not be accessible.
Demonstrated in code sample below:
class Example4{
val publicObj = object{
val x = 1
}
private val privateObj = object{
val x = 2
}
fun showcase(){
val scopedObj = object{
val x = 3
}
println(publicObj.x) // ERROR : unresolved reference: x
println(privateObj.x) // OK
println(scopedObj.x) // OK
}
}
Differences between Anonymous, Singleton & Companion Object in Scala
This is a quite long answer but I hope it clarifies a bit potential usage scenarios.
So, why Anonymous object is good if we don't want to reuse?
I think that unlike the other two the term "anonymous object" is not well-defined in the Scala world. I can think of several things that might be called so:
- Some object that you don't assign to any named variable or field. This can happen in several cases. For example consider
foldLeft
on some collection. You want to pass the initial value there but you typically don't need to give it any name as this is a disposable object. Another case is when such object contains some piece of logic you want to use (a kind of strategy pattern). Consider following piece from standardParIterableLike
def count(p: T => Boolean): Int = {
tasksupport.executeAndWaitResult(new Count(p, splitter))
}
This particular implementation uses named method tasksupport
because it wants it to be customizable. But if not that, it might have been something like
def count(p: T => Boolean): Int = {
new ExecutionContextTaskSupport.executeAndWaitResult(new Count(p, splitter))
}
and new ExecutionContextTaskSupport
would be an anonymous object.
Something that should be called an "anonymous type object".
- This happens quite often if you implement an evidence for some type-classes. Consider this example from Play-Json
case class Resident(name: String, age: Int, role: Option[String])
import play.api.libs.json._
implicit val residentReads = Json.reads[Resident]
// In a request, a JsValue is likely to come from `request.body.asJson`
// or just `request.body` if using the `Action(parse.json)` body parser
val jsonString: JsValue = Json.parse(
"""{
"name" : "Fiver",
"age" : 4
}"""
)
val residentFromJson: JsResult[Resident] = Json.fromJson[Resident](jsonString)
Here the object and the class for residentReads
will be generated by a macro behind Json.reads
and you don't care what type it has as long as it implements the Reads
trait.
- Or if you have a template method that depends on some strategy returned. I.e these are the cases when all the caller needs to know about the type is that it matches some specified interface contract (i.e. extends certain
trait
). Consider this piece fromExecutionContextImpl
def fromExecutorService(es: ExecutorService, reporter: Throwable => Unit = ExecutionContext.defaultReporter):
ExecutionContextImpl with ExecutionContextExecutorService = {
new ExecutionContextImpl(Option(es).getOrElse(createDefaultExecutorService(reporter)), reporter)
with ExecutionContextExecutorService {
final def asExecutorService: ExecutorService = executor.asInstanceOf[ExecutorService]
override def execute(command: Runnable) = executor.execute(command)
override def shutdown() { asExecutorService.shutdown() }
override def shutdownNow() = asExecutorService.shutdownNow()
override def isShutdown = asExecutorService.isShutdown
override def isTerminated = asExecutorService.isTerminated
override def awaitTermination(l: Long, timeUnit: TimeUnit) = asExecutorService.awaitTermination(l, timeUnit)
override def submit[T](callable: Callable[T]) = asExecutorService.submit(callable)
override def submit[T](runnable: Runnable, t: T) = asExecutorService.submit(runnable, t)
override def submit(runnable: Runnable) = asExecutorService.submit(runnable)
override def invokeAll[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAll(callables)
override def invokeAll[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAll(callables, l, timeUnit)
override def invokeAny[T](callables: Collection[_ <: Callable[T]]) = asExecutorService.invokeAny(callables)
override def invokeAny[T](callables: Collection[_ <: Callable[T]], l: Long, timeUnit: TimeUnit) = asExecutorService.invokeAny(callables, l, timeUnit)
}
}
Again the caller don't care of the specific type as long as it meets the contract of ExecutionContextExecutorService
and particularly we don't care that it is based on ExecutionContextImpl
rather than any other implementation.
And actually case #1 and #2 (i.e. "an anonymous object of an anonymous type") are often combined if you need to pass somewhere a piece of work that for some reasons doesn't fit simple Function
interface (either because it needs more than one life-cycle method or for historical compatibility reasons). The prime example of this is java.lang.Runnable
. And here is another example from ExecutionContextImpl
:
// As per ThreadFactory contract newThread should return `null` if cannot create new thread.
def newThread(runnable: Runnable): Thread =
if (reserveThread())
wire(new Thread(new Runnable {
// We have to decrement the current thread count when the thread exits
override def run() = try runnable.run() finally deregisterThread()
})) else null
The Thread
class requires Runnable
as a piece of work to execute and we want to wrap the runnable
we've got as a parameter with another one that will call deregisterThread
at the end but we don't care about the name of the object or its actual type.
what's the real purpose of Companion Object?
I can think of several major reasons to use Companion Objects.
- Something that in Java world would be a
static
method or astatic
field. For instance assume you write you custom arbitrary-precision arithmeticBigInt
. Where would you put well-known constants such aszero
so they would be accessible from the outside? The companion object is the answer. Another quite typical usage for this kind of companion objects is means to provide some factory methods (typically viaapply
) so for example you can write
List.empty
List(1, 2, 3)
without the new
keyword
- You have some class and you want to provide some shared default instance for it. It is not necessary a singleton in terms that you are quite OK with creating more instances of that class. For example
scala.util.Random
defines both class and a companion object as
object Random extends Random
so you can do just
Random.nextInt
- Something that is probably most deservedly might be called a "companion object". You have some hierarchy of classes and a piece of logic that should be bound to each class in the hierarchy but is not of the type of the classes in the hierarchy. This might sound a bit complicated but is not that hard. The
scala.concurrent
package employs this idea a lot. Consider for example:
abstract class GenTraversableFactory[CC[X] <: GenTraversable[X] with GenericTraversableTemplate[X, CC]]
extends GenericCompanion[CC] {
private[this] val ReusableCBFInstance: GenericCanBuildFrom[Nothing] = new GenericCanBuildFrom[Nothing] {
override def apply() = newBuilder[Nothing]
}
def ReusableCBF: GenericCanBuildFrom[Nothing] = ReusableCBFInstance
// some other stuff
}
which a few levels down to inheritance tree is implemented by the List
companion object
object List extends SeqFactory[List] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, List[A]] =
ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, List[A]] = new ListBuffer[A]
// some other stuff
}
This canBuildFrom
is actually used by many collection methods that transform them into other collections such as ++
or map
. Moreover this clever trick allows you to write something like this with mapping to other collection type:
val list: List[Int] = Vector(1, 2, 3).map(x => 2 * x)(breakout)
c# anonymous object, why only sometimes contains the field definitions?
This isn't specific to anonymous types. Everything inherits from object
which means that you can implicitly cast anything as object
.
Calling a method that returns an anonymous type and assigning it to a variable declared as object
is the same as doing this:
object obj = new { avg = 2, hi = 3, lo = 1 };
object
doesn't have properties like avg
, hi
, etc., so Visual Studio doesn't display them and if you type them they won't compile.
To illustrate using something other than an anonymous type:
var s = "Hello!";
object o = s;
There's only one string
. Both s
and o
refer to a string
. But s
is cast as a string
and o
is cast as an object
.
So you can do this:
var s = "Hello!";
object o = s;
var l = s.Length;
...but you can't do this:
var s = "Hello!";
object o = s;
var l = o.Length; // object doesn't have a Length property.
If you do this:
var obj = new { avg = 2, hi = 3, lo = 1};
...using var
means that the type is inferred. Whatever you're assigning to it, that's what the type is. In this case, behind the scenes, the compiler is actually creating a new type, so it behaves as if you had defined a type with those properties.
Anonymous types like this are handy for use within a method, but they're not meant for passing values between methods. For that either a class, struct, or tuple is better.
Creating an anonymous object who must have the dot in Key name and put it inside another anonymous object
Solved using Dictionary
, then passed it inside an anonymous type obj
:
IDictionary highlitsFieldsContainer = new Dictionary<string, object>();
// ... some code
highlitsFieldsContainer["bodyText.exact"] = new { };
highlitsFieldsContainer["title.exact"] = new { };
var fieldsContainer = new
{
fields = highlitsFieldsContainer,
};
// OUTPUT: fieldsContainer = { fields = { bodyText.exact = {}, title.exact = {} } }
And used a RouteValueDictionary class
to read that values when elasticsearch
send his response.
RouteValueDictionary _res = new RouteValueDictionary(dynamicResponse.highlights);
if (_res["shortDescription.exact"] != null)
{
// ...
}
When does the anonymous objects get deleted from memory and when it is recommended to use them?
“Anonymous object” is not a standard term, it's a descriptive term. I would interpret it as an object without a name. Objects with names are called variables or data members.
In the expression
MyClass().disp()
you're calling the member functiondisp
on a temporary object of classMyClass
. The lifetime of the temporary object extends [1]to the end of the full expression. Which in C++ standardese, if I recall correctly, is called the full-expression.The
new
-expressionnew MyClass
allocates memory for a newMyClass
object, and creates a newMyClass
object in that chunk of memory. The expression produces a pointer to the new object. You can store that pointer in a variable and use it in a laterdelete
expression to destroy the object and deallocate its memory.The expression
new MyClass(300)
is the same except an argument is provided for theMyClass
constructor. Thenew
-expression syntax also provides a notation to specify arguments to the allocation operation. But that's more advanced, very seldom needed, and anyway, as a beginner you should preferentially never use rawnew
ordelete
, but instead standard library containers and strings.
If there is no corresponding delete
for a new
then the object lives till the end of the program execution. If this is a machine with an operating system then the OS will reclaim the memory. However, the OS knows nothing about C++ objects so the object destructor is then not called, and hence cleanup specified in the destructor will not be performed.
You ask where new
is useful. Generally when the desired lifetime for an object does not fit a scope (the nested lifetimes of local automatic variables), and/or where one needs a dynamic size object. Using new
to control lifetime is less of an issue with efficiently movable objects as in C++11 and later, and for dynamic size preferentially use containers such as std::vector
and strings like std::string
.
[1] More generally a temporary object can be bound directly to a local reference, in which case its lifetime is extended to the lifetime of the reference, i.e. out the enclosing block.
Can you create a Java array of an anonymous class?
Remember that new Object() {...}
gives you a value not a type.
So, here is how you could create an array of instances of anonymous classes:
final Object[] anonArray = new Object[]{
new Object(){
public String foo = "bar1";
},
new Object(){
public String foo = "bar2";
},
new Object(){
public String foo = "bar3";
},
new Object(){
public String foo = "bar4";
}
};
Or if you want an array with the same anonymous class instance 4 times:
final Object anonInstance = new Object(){
public String foo = "bar1";
};
final Object[] anonArray = new Object[]{
anonInstance, anonInstance, anonInstance, anonInstance
};
Or if you want 4 distinct instances of the same anonymous class:
final Object[] anonArray = new Object[4];
for (int i = 0; i < anonArray.length; i++) {
// Just to show we can do this ....
final String bar = "bar" + 1;
anonArray[i] = new Object(){
public String foo = bar; // Look!
};
}
Note that in all of the above the array type is Object[]
not "array of the anonymous subclass of Object
". It is difficult to conceive that this would matter, but if it did matter you would need to resort to reflection to create the array class. (See @ernest_k's answer.)
Or just declare an array of an appropriate custom class or interface, and create anon subclasses from that class / interface. Anonymous subclasses of Object
are not exactly practical ...
Anonymous object Creation and GC
If an instance is not available (reachable) within the code, then it's dead. When the gc runs, it identifies the live set, not the set of dead objects. The JVM has its own way of keeping track of live objects.
The collector will trace the live set, marking all live objects.
Then the collector will, depending on the type, either move the live set to another memory area (copying collector) or traverse the heap, deleting dead objects as it finds them and optionally compacting the heap.
In your specific case, the fact that an anonymous object has no specific reference doesn't really matter to the gc since it has its way of keeping track of live and dead objects.
Related Topics
What Does *& Mean in a Function Parameter
How to Combine Std::Bind(), Variadic Templates, and Perfect Forwarding
Fine Tuning Hough Line Function Parameters Opencv
Why Is Taking the Address of a Temporary Illegal
Generate N Random Numbers Within a Range with a Constant Sum
What Do the C and C++ Standards Say About Bit-Level Integer Representation and Manipulation
How to Differentiate (When Overloading) Between Prefix and Postfix Forms of Operator++? (C++)
C++ Class or Struct Compatiblity with C Struct
C++ -- How to Overload Operator+=
Assert That Code Does Not Compile
Is Incrementing a Null Pointer Well-Defined
Drawing in a Win32 Console on C++
Is There a Gcc Preprocessor Directive to Check If the Code Is Being Compiled on a 64 Bit MAChine
How to Properly Delete a Pointer to Array
Convert Bitmap to Png In-Memory in C++ (Win32)
Speed Accessing a Std::Vector by Iterator VS by Operator[]/Index