开发者

Are raw C++ pointers first class objects?

开发者 https://www.devze.com 2022-12-27 17:06 出处:网络
According to Wikipedia: An object is first-class when it: can be stored in variables and data structures

According to Wikipedia:

An object is first-class when it:

  • can be stored in variables and data structures
  • can be passed as a parameter to a subroutine
  • can be returned as the result of a subroutine
  • can be constructed at runtime
  • has intrinsic identity (independent of any g开发者_如何学编程iven name)

Somebody had once told me that raw pointers are not first class objects while smart pointers like std::auto_ptr are. But to me, a raw pointer (to an object or to a function) in C++ does seem to me to satisfy the conditions stated above to qualify as a first class object. Am I missing something?


The definition in Wikipedia of "first-class" is incorrect. In a programming language, an entity is considered to be "first-class" if it does not require any special treatment by the compiler and can be interpreted, understood, used, etc. just like any other object in the language. The reason pointers in C++ are not first class objects is that *p for a pointer p is not interpreted as simply invoking an overloaded operator* like it would be for any other object; instead, the compiler has to treat p specially based on the fact that it is a pointer type. When passing a pointer or a reference you cannot simply pass any value object (and some of those value objects happen to be pointers), but you are actually saying that it is a different type (a pointer type or a reference type, in place of a value type), and its interpretation / usage is subject to its type.

A good example of a language where all objects are first-class is Python. In Python, everything has some sort of type associated with it, it can be treated as an object, it can have members, functions, etc. As an extreme example, even functions in Python are objects that simply contain code and happen to be callable; in fact, if you try to call the function using the __call__ member function (which is akin to overloading operator() in C++, and which other non-function objects can provide), an ordinary function will return a function wrapper as a result (so that you don't have to treat functions as a special case). You can even add members to functions like you would to other objects. Here is an example of such a thing:

>>> def f(x):
...     return x;
... 
>>> func = f;
>>> print f.__class__

>>> print f(5)
5
>>> print f.__call__(5)
5
>>> f.myOwnMember = "Hello world!"
>>> print f.myOwnMember
Hello world!

I apologize for the Python in a C++ post, but it is hard to explain the concept without the contrast.


The Wikipedia article is shit (for once I agree with "citation needed"), but you are not missing anything: according to the Wikipedia definition, and also according to any sane definition, raw C++ pointers are first-class objects.

If anyone would like to volunteer to help me with some searches through Google Scholar, I would really like to see that Wikipedia article fixed. I am a subject-matter expert, but I am also extremely busy—I would love to have a partner to work on this with.


Actually both - "Pointers are FCO" and "Pointers are not FCO" - are correct. We need to take the statements in the respective context. (FCO - First Class Object)

When we talk of a 'pointer' in C++, we are talking of a data type that stores the address of some other data. Now whether this is FCO or not, depends really on how we envisage to use it. Unfortunately, this use semantics is not built-in for Pointers in C++.

If we are using pointers merely to 'point' to data, it will satisfy the requirements of being an FCO. However, if we use a pointer to 'hold' a data, then it can no longer be considered an FCO as its copy and assignment semantics do not work. Such 'resource handling' pointers (or more directly referred as 'raw pointers') are our interest in the context of Smart Pointer study. These are not FCO while the corresponding Smart Pointers are. In contrast, mere tracking pointers would continue to meet the requirements for an FCO.

The following paragraph from "Modern C++ Design" book nicely elucidates the point.

I quote from the Chapter on Smart Pointers:

An object with value semantics is an object that you can copy and assign to. Type int is the perfect example of a first-class object. You can create, copy, and change integer values freely. A pointer that you use to iterate in a buffer also has value semantics—you initialize it to point to the beginning of the buffer, and you bump it until you reach the end. Along the way, you can copy its value to other variables to hold temporary results.

With pointers that hold values allocated with new, however, the story is very different. Once you have written

Widget* p = new Widget; the variable p not only points to, but also owns, the memory allocated for the Widget object. This is because later you must issue delete p to ensure that the Widget object is destroyed and its memory is released. If in the line after the line just shown you write

p = 0; // assign something else to p you lose ownership of the object previously pointed to by p, and you have no chance at all to get a grip on it again. You have a resource leak, and resource leaks never help.

I hope this clarifies.


As Mike commented there seems to be a bit of confusion with the word Object here. Your friend seems to be confusing between objects as in "first class objects" and Objects as "instances of C++ classes", two very different things where the word object is used for two things completely different.

In Object Oriented programming, the word Object is used to speak of some data structure gathering datafields and methods to manipulate them. With C++ you define them in classes, get inheritance, etc.

On the other hand in the expression "first class object" the word object has a much broader meaning, not limited to Objects of object oriented languages. An integer qualify as a first class object, a pointer also do. I believe "Objects" with the other meaning does not really qualify as first class object in C++ (they do in other OO programming languages) because of restrictions on them on parameter passing (but you can pass around pointers or references to them, the difference is not so big).

Then the things are really the opposite of what you friend said: pointers are first class objects but are not instances of C++ classes, smart pointers are instances of C++ classes but are not first class objects.


From wiki:

In computing, a first-class object (also value, entity, and citizen), in the context of a particular programming language, is an entity which can be passed as a parameter, returned from a subroutine, or assigned into a variable.1 In computer science the term reification is used when referring to the process (technique, mechanism) of making something a first-class object.[citation needed]

I included the entire entry in wiki-pedia for context. According to this definition - an entity which can be passed as a parameter - the C++ pointer would be a first class object.

Additional links supporting the argument: catalysoft wapedia

reification: referring to the process (technique, mechanism) of making something a first-class object

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号