tags:

views:

202

answers:

5

What types in C++ can be instantiated?

I know that the following each directly create a single instance of Foo:

Foo bar;
Foo *bizz = new Foo();

However, what about with built-in types? Does the following create two instances of int, or is instance the wrong word to use and memory is just being allocated?

int bar2;
int *bizz2 = new int;

What about pointers? Did the above example create an int * instance, or just allocate memory for an int *?

Would using literals like 42 or 3.14 create an instance as well?

I've seen the argument that if you cannot subclass a type, it is not a class, and if it is not a class, it cannot be instantiated. Is this true?

+2  A: 

in C++ an 'instance' and 'instantiate' is only associated with Classes

note however that these are also english words that can have conversational meaning. 'pointer' is certainly a class of things in the english usage and a pointer is certainly an instance of that class

but in c++ speak 'pointer' is not a Class and a pointer is not an Instance of a Class

see also - how many angels on pinheads

pm100
however there are other languages (smalltalk for example) where everything is an object, so you do get instances of integers' etc.
pm100
"in C++ an 'instance' and 'instantiate' is only associated with Classes" - source?
Pavel Minaev
+2  A: 

The concept of an "instance" isn't something that's really intrinsic to C++ -- basically you have "things which have a constructor and things which don't".

So, all types have a size, e.g. an int is commonly 4 bytes, a struct with a couple of ints is going to be 8 and so on. Now, slap a constructor on that struct, and it starts looking (and behaving) like a class. More specifically:

int foo; // <-- 4 bytes, no constructor

struct Foo
{
  int foo;
  int bar;
}; // <-- 8 bytes, no constructor

struct Foo
{
  Foo() : foo(0), bar(0) {}
  int foo;
  int bar;
}; // <-- 8 bytes, with constructor

Now, you any of these types can live on the stack or on the heap. When you create something on the stack, like the "int foo;" above, goes away after its scope goes away (e.g. at the end of the function call). If you create something with "new" it goes on the heap and gets its own place to live in memory until you call delete on it. In both cases the constructor, if there, will be called during instantiation.

scotchi
+1  A: 

It is unusual to do "new int", but it's allowed. You can even pass 0 or 1 arguments to the constructor. I'm not sure if "new int()" means it's 0-initialized (I'd guess yes) as distinct from "new int".

When you define a value on the stack, it's not usually called "allocating memory" (although it is getting memory on the stack in theory, it's possible that the value lives only in CPU registers).

Literals don't necessarily get an address in program memory; CPU instructions may encode data directly (e.g. put 42 into register B). Probably arbitrary floating point constants have an address.

wrang-wrang
I'm mainly looking for the answer of if an `int` and other built-in types can be *instantiated*. I assume, based on other answers and your answer, an `int` has a constructor thus can have an instance, correct?
strager
No, int does not have a constructor. C++ distinguishes between POD and non-POD types, where POD types can have constructors, member functions, private member variables, etc., and non-POD types can't.
Charles Salvia
POD structs do have constructors. They do not have _non-trivial_ constructors.
Pavel Minaev
+3  A: 

As far as I can tell, you're really just asking about terminology here. The only real distinction made by the C++ standard is POD types and non-POD types, where non-POD types have features like user-defined constructors, member functions, private variables, etc., and POD types don't. Basic types like int and float are of course PODs, as are arrays of PODs and C-structs of PODs.

Apart from (and overlapping with) C++, the concept of an "instance" in Object-Oriented Programming usually refers to allocating space for an object in memory, and then initializing it with a constructor. Whether this is done on the stack or the heap, or any other location in memory for that matter, is largely irrelevant.

However, the C++ standard seems to consider all data types "objects." For example, in 3.9 it says:

"The object representation of type T is the sequence of N unsigned char objects taken up by the object of type T, where N equals sizeof(T)..."

So basically, the only distinction made by the C++ standard itself is POD versus non-POD.

Charles Salvia
Quoting the standard is great. Thanks! Looks like a step in the right direction.
strager
Your statement "Basic types like `int` and `float` are of course non-POD, as are arrays of PODs and C-structs of PODs." seems incorrect. Do you mean to replace "non-POD" with "POD" and vice versa?
strager
Right, sorry - that was a typo. I edited the post somewhat, and fixed that mistake.
Charles Salvia
POD structs do have constructors (as any struct/class/union with no explicitly defined constructor does). Those constructors are "trivial", as C++ spec calls them, but they exist nonetheless.
Pavel Minaev
True: POD structs have implicit constructors. If you actually define a constructor the object is no longer POD.
Charles Salvia
+4  A: 

So long as we're talking about C++, the only authoritative source is the ISO standard. That doesn't ever use the word "instantiation" for anything but class and function templates.

It does, however, use the word "instance". For example:

An instance of each object with automatic storage duration (3.7.2) is associated with each entry into its block.

Note that in C++ parlance, an int lvalue is also an "object":

The constructs in a C++ program create, destroy, refer to, access, and manipulate objects. An object is a region of storage.

Since new clearly creates regions of storage, anything thus created is an object, and, following the precedent of the specification, can be called an instance.

Pavel Minaev
Very cool. Thanks. =]
strager
This is probably the best answer so far. The differences between the C++ standard and general OOP terminology is interesting. Most OOP programmers would probably not call something like `int x` an instance of an `int`, nor would they be likely to refer to an `int` as an object; but nonetheless it would be technically correct to refer to it as such.
Charles Salvia
Yes, "instance" as quoted by Pavel is not being used at all in the usual OOP sense, since it says "instance of an object", not "instance of a type". I think it could be replaced by "a different object with..." and mean the same thing. I speculate most OOP programmers wouldn't refer to an int as an object because they were trained on Java, where indeed an `int` is not an `Object`. Purer OOP languages don't make exceptions for built-in types, so their integers are objects. In Ruby you can dynamically monkey-patch methods to the class which represents them, to make `3.minutes` equal 180.
Steve Jessop