Steven T. Hatton wrote:
When a variable goes out of scope, a destructor is called.
That is a variable. What about anonymous objects? I believe such a concept is meaningful in C++, e.g., the elements of a linked list.
Yes, but you should always keep a pointer to an object until it is deleted. It is possible to create an anonymous object (just use new X(); without an assignment) or to throw away a pointer (just create an object with new in a function and don't pass the pointer value when the function finishes), but these are bad practices. Unfortunately C++ doesn't have any garbage collection like java does, though you could look at the auto_ptr class. Distinguish between 'anonymous object', which is not used as a term in C++ AFAIK, and 'anonymous class', which is. For example, below, ratio is an object of an anonymous class, used together with operator overloading to create a local object that behaves like a function. This technique is a bit obscure, but becomes useful in the Standard Template Library. #include<iostream> using namespace std; int main(){ struct { double operator()( double x, double y ){ return x / y; } } ratio; double d = ratio( 1, 2 ); cout << d << endl; cout << 1 / 2 << endl; exit( 0 ); }
If I start removing elements form such a list without explicitly destroying them, I could end up with object occupying memory, yet having no reference to them withing my program. Is this not true?
Yes, which is why you should handle this carefully. For example, you could use a class to handle the linked list, with a member function for adding/removing elements. Then the member function is responsible for tidying up the heap. Here, I would use the STL or Qt version of the linked list, which already handles such things safely.
If you've been following any of the saga of my KDE/QT/KDevelop woes, you will understand that I haven't had a lot of time to follow up on these topics. I did get to thinking about your comments regarding defining a class in the header, and it's methods in the 'source' file. There are a few things I'm not sure of regarding classes. With time, and further reading, I suspect these will become clear, but it probably doesn't hurt to mention them.
As I understand things, the class definion itself is in a favored position to go on the stack rather than the heap. This could mean different things depending on the details. I assume the static members would only appear once in the run-time image. If we say a method gets put on the stack, what we really mean is it's local variables and return pointer are placed on the stack. Methods defined within the body of the class definions are default /inline/ meaning they 'should' go on the stack.
The separation between class declaration and class definition affects compiling rather than where a class is defined. In fact, you can't define a class on the heap, only objects of the class. Your code may contain more than one copy of a class member function definition, but only as an accident of the way it was compiled. If you separate the declaration from the definition by using a header file, you don't get copies of member functions in the object code.
My understanding is that member variables cannot be initialized within the class definiton.
At least, not within the class declaration. This wouldn't make sense except for static member variables because they take different values for different classes. Static member variables can be initialised outside the class declaration with a statement like double A::pi = 3.1415926536 I think you can initialise ints withing the declaration. Usually, you would only initialise static consts and not in the header file (otherwise you'll get an error if you read the header twice). Functions can, however, be completely defined within the
class definition.
Yes, but their local variables are not defined until the member function is called and each object gets it's own copy of a nonstatic member function's variables. And here again, is a point of some confusion.
Experimentation indicates to me that classes *are* initialized by their default constructor when declared in the body of the class declaration. So
class MyClass { private: MyMember mm; int myInt; }
If MyMember has an initializer in its constructor, its variables can be initialized by the implicit invocation of the constructor resulting from the declaration. myInt, however will not be initialized, and cannot be initialized at the point shown above.
Yes: MyMember is an object but MyClass is a class.
Part of what I'm trying to get a handle on is the way a class instance and it's members will be represented in memory. It seems possible, if not likely, some parts may go on the stack while other perts go in the heap. In particular, it seems member variables might go on the heap.
It's probably not useful to think about stack and heap unless you're writing your own compiler. Think instead that anything created with new must be destroyed by delete; otherwise the thing gets destroyed when it is out of scope.
The original question that started me down this road has to do with the actual size of a pointer to an object of a given type, and also the amount by which such a pointer will be incremented with, for example ptr++.
ptr++ will be incremented by the size of the type to which ptr is a pointer.
Are these notions about pointer size and pointer incrementation easy to explain?
Relatively. The compiler knows the size of an object of any given type and know the type of any given pointer; so given that ptr has type *my_type, ptr++ will add sizeof( my_type ) to ptr. This fact is only useful, of course, if you know that an array or my_type occupies a contiguous area of memory in which each my_type object occupies sizeof(my_type).
STH
-- JDL