From Java to C++ Confusion

Started by
5 comments, last by Zahlman 14 years, 1 month ago
I'm just learning C++, coming from Java and I am confused. Q1. From what I understand, I can just pass around references and pointers of objects to functions and change the original value directly without using setter/getter functions. This doesn't sound right to me. What am I missing? Q2. When using the "new" keyword to allocate memory on the heap (I think I got this right) after calling the destructor, I have to still use the delete keyword to free the memory? Q3. Are namespaces the equivalent of packages in Java? Thanks for looking.
Advertisement
A1: It depends on whether the items you want to change have been declared in a protected or private block. Any public member variable can be modified directly given a reference or pointer to its containing object. Protected member data may be modified internal to the containing class, and by derived classes. Private member data may only be accessed from the outside, or by derived classes, if a function to modify it is provided.

In general, you should prefer to avoid setters and getters where possible -- or more precisely, you should prefer to avoid simple mutable data period, and instead prefer to have an objects state maintained as a matter of course through the natural interactions with its interface. Obviously this is not always the "correct" way to do things (such as with a mathematical vector class, for instance) but its something to strive for.

A2: You should almost never call a destructor manually. calling the appropriate version of delete will call the appropriate destructor when properly used.

A3: I'm not exactly sure what a package entails in Java, but namespaces in C++ are just a hierarchical structure in which to put other names. They have some impact as far as name lookup (google "koenig lookup") goes, but they don't have any real structural impact outside the source code, which I suspect Java does from what I recall.

throw table_exception("(? ???)? ? ???");

I would hate to come from java to C++. After java, C++ seems so more
overly complicated.
Edge cases will show your design flaws in your code!
Visit my site
Visit my FaceBook
Visit my github
Thanks for the detailed reply Rayvne.

@Concentrate: I actually want to learn C++ for the reason that it is more complicated. I feel that C++ would be a good language for anyone to learn if they wanted to better understand some of the "magic" that Java uses in an attempt to be a more simplified language.
Quote:Original post by X Abstract X
Q3. Are namespaces the equivalent of packages in Java?

Largely yes. The biggest difference is that in Java your package hierarchy must match the actual directory layout, but in C++ you can organise the two however you feel fit (including having multiple namespaces within the same file if you want). Although generally I find it helpful to organise the files by namespace anyway.
Quote:Original post by X Abstract X
I can just pass around references and pointers of objects to functions and change the original value directly without using setter/getter functions.

What exactly do you mean by that? Assignment on the object? Something like this?
some_class a;some_class* p = &a...*p = b;

If you want to disallow this, you have to hide the assignment operator.
some_class{...private:    some_class& operator=(const some_class&);...};
Quote:Original post by X Abstract X
I'm just learning C++, coming from Java and I am confused.


This is partly because, as I'll demonstrate, you didn't actually know Java as well as you thought you did.

Quote:Q1. From what I understand, I can just pass around references and pointers of objects to functions


Yes, you can do this in C++. But not only can you also do it in Java, you automatically do it in Java. Every variable in Java of a class type is actually a sort of pointer or reference (which has been made safe with some automatic bounds checking and restrictions on what you can do with it). You don't store the underlying data. That's why when you write something like 'MyClass a, b; b = a; a.modify();', 'b' gets modified too: because it's actually the underlying data that gets modified, and 'a' and 'b' both refer to it.

After all, why did you think it's called a NullPointerException? :) The "Java has no pointers" marketing line is just that: a marketing line.

Quote:and change the original value directly without using setter/getter functions.


Yes, you can do this in C++. But not only can you also do it in Java, you have to do work to prevent it in Java (marking things 'private').*

Quote:This doesn't sound right to me. What am I missing?


What you're missing is that getter/setter functions have nothing to do with Java whatsoever. They have to do with what some people think is "object-oriented programming".

Those people are, generally speaking, completely and utterly wrong, by the way.

The point of marking data 'private' is so that manipulating the object is done through its public interface - i.e. the parts that you identify as 'public'. The point is to design an interface that represents the things that the object can logically do. The problem with getters and setters is that they don't actually create this abstraction: when you use getters and setters, you are still thinking of the object as just a collection of data, the sum of its parts.**

* In Java, the default access is package-level, which might as well be public for small projects. In C++, there is no concept of package-level access because there is no concept of packages. The 'default' access depends on whether you labelled your class as a 'class' or as a 'struct'.

** Used correctly and in moderation, this isn't really true. But there are all kinds of people out there recommending getters and setters for every member, writing tools to generate them automatically, etc. It is all nonsense. The problem is the concept of getters and setters. If it makes sense for your interface to have a function that happens to do what a getter or setter does, then by all means write it. But do actually design the interface.

Quote:Q2. When using the "new" keyword to allocate memory on the heap (I think I got this right)


Yes, that's how you allocate memory on the heap manually.

But you should almost never allocate memory on the heap manually in C++, because you are responsible for memory management - there is no GC.

Quote:after calling the destructor,


No. You never* call the destructor yourself. The destructor is called by C++ when you use 'delete' on something that was created with 'new', or at the end of the scope of a local variable (or temporary object in the middle of an expression - the scope for the temporary, normally, is just the expression itself).

Quote:I have to still use the delete keyword to free the memory?


You must arrange for everything that you allocated yourself to be deallocated yourself, exactly once, in the corresponding way. If you allocate a single item using 'new', use 'delete'. If you allocate an array with 'new[]', use 'delete[]'.

This does not mean that the words 'new' and 'delete' will appear the same number of times in the program, incidentally.

* Almost never. Normally, when you call a constructor, the actual object memory allocation is done automatically - whether on the heap because you used 'new', or on the stack when you declared a local variable. There is approximately one case, though, in which it's really useful to take already-allocated memory and transform it into an object using its constructor - using something called 'placement new'. When an object has memory allocated in a special way, and then is created using 'placement new', then cleaning up requires undoing all of that in the reverse order: manually calling the destructor (which undoes 'placement new'), and then deallocating the memory (which might involve delete[], but called on a char* that represents the raw memory allocation). However, you will never have to do this, because that one useful case is already wrapped up by the standard library, in a class called std::vector.

Quote:Q3. Are namespaces the equivalent of packages in Java?


They're as close as you're going to get. But C++ doesn't offer anything like Java's model for 'import'ing.

You need to have separate header files that describe interfaces (without providing any implementation), and '#include' (a literal copy-and-paste) into other places that need the functionality, so that the compiler knows things like "by the way, 'foo' is the name of a function that's defined somewhere else". Each source file (more accurately, translation unit - the result of running the preprocessor on a source file, and doing all that copy-and-paste and macro-expansion work) is compiled separately, with stubs referring to the functions in other places. Then a separate (technically, but usually bundled together with the compiler) process called the 'linker' joins everything up into an executable.

Namespaces can help with organizing this mess, but they don't make the compilation model work any differently.

This topic is closed to new replies.

Advertisement