Sign in to follow this  

Going C++

This topic is 4733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been programming in C for a while now, but I'd like to know C++ as well. I've seen they are VERY similar languages, but this new "objects" thingy is actually hard to understand, so...do you know of any tutorials you would recommend? I just need an edge, some basic concepts behind the idea of object-oriented programming and the new syntax behind classes and that sort of things... So, where should I look? Thanks!

Share this post


Link to post
Share on other sites
Here you go, a brilliant document that explained the main differences to me. Credits to the author!

http://www.4p8.com/eric.brasseur/cppcen.html

Always remember this: C is not a subset of C++. Rather, C++ is a totally different language with its own standard. You'll especially notice this when a C program doesnt compile with the g++ compiler because the .h files are not exactly the same in both languages. In fact, it's better not to switch between languages at all and just go for either C or C++. Recently I stepped over from C to C++ and I find some C++ features to be very handy, like exceptions and classes.

Good luck and have fun coding,
Bas

Share this post


Link to post
Share on other sites
With the risk of getting massive flames, why do yuo want to switch to C++? I am a C programmer for more than 2 years, and I didn't find anything useful (FOR ME) in C++.

Share this post


Link to post
Share on other sites
Quote:
Original post by Raduprv
With the risk of getting massive flames, why do yuo want to switch to C++? I am a C programmer for more than 2 years, and I didn't find anything useful (FOR ME) in C++.

Well, there are some features found in C++ that really makes it a better C. You don't have to use the object oriented features at all, just stay procedural if you prefer. But things like namespaces, operator overloading and templates are very useful features, even if you want to stay away from OOP. So it's definitely worth learning at least these parts of C++, because they will make your C code cleaner, more elegant and easier to maintain.

Share this post


Link to post
Share on other sites
The only procedural C++ feature that I find useful is the operator overloading, but I don't find it THAT useful. In fact, sometimes it can make the code even more confusing, especially for someone who is not familiar with your program.
Namespaces, well... I use long global variables, and their name is pretty descriptive so I don't really need namespaces.
Oh, and you can also put values for variables in headers. That'snice too.

Of course, there is nothing wrong with using those features, or even OOP stuff, but if you are happy with C as it is (I personally am), I don't think you should move to C++ just because it's 'trendy'.

Share this post


Link to post
Share on other sites
Quote:
Original post by basananas
Here you go, a brilliant document that explained the main differences to me. Credits to the author!

http://www.4p8.com/eric.brasseur/cppcen.html

well, the number 6 in that thingy is wrong...

for (int i = 0; i < 10; ++i) {
cout << i << endl;
// i is in scope
}

cout << i << endl;
// ISO standard says i is out of scope
// msvc doesn't care [it was a bug in visual c++ 6, it doesn't warn in .net 2003 but can probably be configured to do so]
// the version of gcc I tried complained, mentioned the iso standard



also, templates, even though a pain, make abiguity with function overloading completely go away

the ambiguity would be something like having:
double sin(double);
float sin(float);

so, if called with a float, which one will get called? a float can be up-cast to a double. You'd think the compilier would be smart enough to keep it a float [it isn't], but what about an int? which should it be cast to?...

the implementation of template functions doesn't have to be type independent, you can write a different template function for float and one for double...


virtual functions are useful too, if a pain. If you felt like it you could make a 3d engine where all objects have their own virtual draw method, and the engine doesn't need to care about their type [terrain, nurbs, catmul clark subdivision surface, vertex buffer]...
[performance wise it might not be that great of an idea]

Share this post


Link to post
Share on other sites
Just going from C to C++ you will immediately benefit from templates and modules. In C you also have to deal with modules but it's a bit of a pain to set up because you have to impose the structure on it whereas it's done for you in C++ thru objects. Then the next step up is OOP or polymorphism and some other stuff. The main idea behind this is to tell the object what to do and not to pull data or its internal representation out of the object for anyone to see. Whether or not this will work for you is up to you and your project. Some things fit into OOP and some don't. But object based programming applies to both C and C++ and it's what most of us will eventually end up using if not already in a larger program.

Share this post


Link to post
Share on other sites
Quote:
Original post by sit
well, the number 6 in that thingy is wrong...


I've tried it myself and I have to conclude that you are right! I always used "for (int i..." like the scope was only within the for loop itself, but that document claims that you can access i even after the loop has ended. It's a nasty mistake in what is actually a great document, and I've emailed the writer about it.

Well found by the way!

Bas

Share this post


Link to post
Share on other sites
that document does not claim that ..

The C++ for scope history is a nasty blight on the language ... the problem is because of the compiler vendors and the standards body disagreeing ..

The standard says that a for loop defines a new scope .. so if you declare for(int i ...) then you CANNOT use I below the for loop ... this is the 100% completely correct truth.

BUT, the compiler vendors has already impmented this the Other way .. where if you wrote for(int i) .. it was the same as writing int i;for(i ... - so that the i was in scope outside of the for loop ... which is only ever a problem in cases like this:

for(int i=0 ...
{
}

for(int i=0 ...)
{
}

in standard c++ this is correct ... in modern c++ on modern compilers this is correct ... but on old compilers (Visual C++ 6) the default settings made this a compiler error ... BUT EVEN ON VISUAL C++ 6 this was a compiler setting you could set EITHER WAY - its just that the correct way didn't work with windows, because the windows API had code counting on the old way ...

this has since been corrected.

Share this post


Link to post
Share on other sites
want a reason to compile in C++ mode instead of C mode? how about:

the STL ... oh my god the glory of <deque> <map> <string> <algortihm> <list> <vector>

and then, when you get a little more advanced <functional>

oh, the power of the template ... how do I love thee, shall I count the ways

Share this post


Link to post
Share on other sites
O_O Wow! It seems I have plenty of things yet to understand...I thought there were fewer differences between C and C++.
Raduprv, I know what you mean, I've been using C for a while and haven't had any problems with it. I find it truly powerful, but I'd just like to know what C++ is. I know many developers switched to C++, but I don't know why...I mean, they must have a reason to do so... After understanding the concepts underneath C++ I'll decide whether it is for me or not...
I have another question now...all this things: OOP, templates, exceptions, etc. would make C++ qualify as a "higher-level" language compared to its older sibling, C?

Share this post


Link to post
Share on other sites
C++ can get as low level as C, but you don't want to do that in most cases.
For example, you should use std::string instead of char* arrays most of the time.

Share this post


Link to post
Share on other sites
noVum, "std" in that case would be a predefined class or namespace which allows you to work witch strings, right? If that's the case, where's its definition?

Share this post


Link to post
Share on other sites
std is a namespace that all C++ standard library elements are in ...

the string is defined in the header "string" included as follows:


#include <string>
#include <iostream>

int main(void)
{
std::string myName = "Keith";
std::cout << myName << std::endl;
return 0;
}



now most people don't use std:: all the time, instead they add a "using" statement which basically imports the std namespace into the current namespace ... like this:


#include <string>
#include <iostream>
using namespace std;

int main(void)
{
string myName = "Keith";
cout << myName << endl;
return 0;
}


Share this post


Link to post
Share on other sites
After reading some of the tips from the page Basananas provided (BTW, great page, save for that little confusion in point 6.), I realized that maybe my knwoledge regarding pointers and references is not that good (or maybe, I became confused while "switching" from C to C++ mode inside my head...err...Protection Fault...err).
Maybe some of you would be kind enough to point out the differences between "*" and "&" in C (which I thought I knew quite well) and those in C++...
I became confused when I saw this piece of code:

using namespace std;
#include <iostream>

double *silly_function () // This function returns a pointer to a double
{
static double r = 342;
return &r;
}

int main ()
{
double *a;

a = silly_function();

double &b = *a; // Now b IS the double towards which a points!

b += 1; // Great!
b = b * b; // No need to write *a everywhere!
b += 4;

cout << "Content of *a, b, r: " << b << endl;

return 0;
}

The third line from main() says "double &b = *a".
I understand how this works...but I don't understand why the "&" is used with b...shouldn't it be something like "double *b = a"...or even (please, don't kill me) "double *b = *a"?
It's been awhile since I had problems dealing with pointers in C...this struck me as a surprise (my coding self steem in now low =( )

Share this post


Link to post
Share on other sites
Quote:
Original post by Xai
that document does not claim that ..

The C++ for scope history is a nasty blight on the language ... the problem is because of the compiler vendors and the standards body disagreeing ..

The standard says that a for loop defines a new scope .. so if you declare for(int i ...) then you CANNOT use I below the for loop ... this is the 100% completely correct truth.

BUT, the compiler vendors has already impmented this the Other way .. where if you wrote for(int i) .. it was the same as writing int i;for(i ... - so that the i was in scope outside of the for loop ... which is only ever a problem in cases like this:

for(int i=0 ...
{
}

for(int i=0 ...)
{
}

in standard c++ this is correct ... in modern c++ on modern compilers this is correct ... but on old compilers (Visual C++ 6) the default settings made this a compiler error ... BUT EVEN ON VISUAL C++ 6 this was a compiler setting you could set EITHER WAY - its just that the correct way didn't work with windows, because the windows API had code counting on the old way ...

this has since been corrected.

the defuault in .NET 2003 is to let the incorrect code compile

the option [tested working] is in project properties, c/c++, Language, "Force Conformance In For Loop Scope"

the default is not to...

when on it complains i is not defined

... I kninda wish there were more "force standardized code" options in visual studio... oh well

Share this post


Link to post
Share on other sites
Quote:
Original post by Pse
double &b = *a; // Now b IS the double towards which a points!

The third line from main() says "double &b = *a".
I understand how this works...but I don't understand why the "&" is used with b...shouldn't it be something like "double *b = a"...or even (please, don't kill me) "double *b = *a"?
It's been awhile since I had problems dealing with pointers in C...this struck me as a surprise (my coding self steem in now low =( )


It's not strange at all that you didn't understand that at first sight, because it's a c++ only feature! :)

In c, you can't make two 'normal' doubles (not pointers) that changed the same memory location, and in c++ you can. You do this by 'double &b = *a'. After that changing b or *a have the same effect. It's new to any c programmer so no need for a low programming self-esteem ;)

Another example from the document that is a little easier to comprehend:

using namespace std;
#include <iostream>

int main ()
{
double a = 3.1415927;

double &b = a; // b IS a

b = 89;

cout << "a contains: " << a << endl; // Displays 89.

return 0;
}





Bas

Share this post


Link to post
Share on other sites
The pointer and reference duality in C++ is quite tricky at first ... Keep in mind that for BOTH of these operators *, and & - the exact meaning in context dependent

In C, you only have items, and pointers ... and the word REFERENCE is simly used to mean the same thing as pointers.


double x; // declares a variable, allocates space for that variable
double *p; // declares a pointer, allocates space for the pointer
void foo(double x); // same as above, a function that passes a COPY of the variable, using space on the stack to hold the variable. This is called Pass-by-value in C.
void foop(double *p); // function accepts a pointer to a variable copying the pointer on the stack, not copying the original variable. This is called pass-by-reference in C.
double x2;
double *p2;

x = x2; // copies the contents of x2 into x;
foo(x2); // copies the contents of x2 into the stack while calling the function
p2 = &x2; // sets the pointer p equal to the address of x2 (& used to be read as the address-of operator in C)
foop(&x2); // copies the address of x2 onto the stack while calling the function
p = p2; // copies the value of p2 (which is the address of x2) into p
foop(p2); // copies the value of p2 (address of x2) onto the stack while calling the function
*p = x; // copies the value of x, into the thing pointed to by p (p holds the address of x2, so this copies x into x2)



Pretty much all you have to think about in C is how many levels of indirection you have on each side and add * or & to make them match. You add * to dereference a pointer, and & to get an address.

Then C++ added references ... and all hell broke loose.

ALL a reference is is a POINTER, maquerading as if it is not a pointer.


double &r = x; // declares a reference to a double, which allocates space for a pointer, but uses the syntax and operations of a double. And initialized to refer to the variable x;
foor(double &r); // declares a function which copies a reference (pointer) to the item passed in, but uses syntax as if it is not a pointer to manipulate it.

r = x2; // copies the contents of x2 into the thing referenced by r (x).
foo(r); // copies the contents of the thing pointed to by r (x2) into the stack
r = *p2; // copies to contenxt of the thing pointed to by p2 into r.
foor(x2); // copies a reference to x2 on the stack
foor(*p2); // copies a reference of the thing pointed to by p2 onto the stack .. .




// assuming
double x;
double &r = x; // declare the referene r to refer to the variable x
double *p = &x; // declare the pointer p to point to the variable x (also - declare the pointer p to be equal to the address of x)

// these should pass the same thing
foo(x);
foo(r);
foo(*p);

// these should pass the same thing
foop(&x);
foop(&r); // someone double check me here?
foop(p);

// these should pass the same thing
foor(x);
foor(r);
foor(*p);


Share this post


Link to post
Share on other sites
Warning! Warning! Implementation details in the above!

References are better thought of as a calling convention. That is, they indicate that something should be "passed by reference".

From what I can tell, using references for variables like that is not very common; more commonly you will see them used on parameters, so that the bit I just wrote makes somewhat more sense.


// C, also in C++
void wibble(int foo) {
foo = 42;
bar = foo * foo; // bar is 1764
// etc.
}

int spam = 23;
wibble(spam); // the change to spam within 'wibble' is not seen here!
ni = spam * spam; // ni is 529!

// C++, using references
void wibble(int &foo) { // foo passed by reference
foo = 42;
bar = foo * foo; // bar is 1764
// etc.
}

int spam = 23;
wibble(spam); // spam is 42 now!
ni = spam * spam; // ni is 1764!

// Getting the same effect in C using a pointer; which is how C++ is likely
// to implement things behind the scenes, but that isn't guaranteed...
void wibble(int* foo) {
*foo = 42;
bar = *foo * *foo; // bar is 1764
// etc.
}

int spam = 23;
wibble(&spam); // wibble() manipulates spam through a pointer
ni = spam * spam; // ni is 1764



The real benefit is code clarity: you don't have to complicate your type calculus by adding another level of indirection (explicitly, anyway) just to specify what is really a calling convention ("this is an out-parameter; allow changes to be seen by the caller"). A level of "call by reference" is conceptually different from a level of pointing (because you can only have one, and there is no inverse operation for it), so it gets its own syntax - and you get to write the rest of the function as if you had a normal value.

There is also an optimization benefit when passing large structs (or classes); so it is common to pass anything that isn't a primitive by reference (and specify a const reference if the function should not change the input).

C++'s typing is overall stronger than C's, so it makes sense to write "int* i" rather than "int *i" (although it's the same old tokenizer so the compiler doesn't care). However, the '&' here is not really a part of the type, so I write "int &i" rather than "int& i".

A caveat here for those with Java experience (or those planning to pick it up) - the behaviour is not the same! Java passes object references by value. The distinction is subtle but it is very definitely there:


// C++
void modify(Foo &input) {
input.wibble(); // ok, even if wibble() changes the contents of a Foo
input = new Foo(); // still OK! and the change will be seen by the caller!
// input = Foo(); <-- error! assigned an auto value that will fall out of
// scope at the end of the function, and crash
}

// Java
public void modify(Foo input) {
input.wibble(); // ok, even if wibble() changes the contents of a Foo
// In fact, we don't have compile-time checks available to prevent us
// from doing that.
input = new Foo(); // This change will NOT be seen by the caller.
}



Implementation-wise, the difference is that C++ adds a level of pointing at the time of the function call, whereas in Java, the pointer is always there and you do everything with the object through that pointer. So if you assign a new object, that's a new pointer value assigned to the *local* variable, and the changes are not seen elsewhere.

Share this post


Link to post
Share on other sites
Zahlman, is that really true about being able to change the thing refered to by a reference and have it seen by the caller?

That would mean that implementationally the compiler is passing an extra level of indirection (a pointer to a pointer), or returning the final reference as an out parameter and performing an assignment ... and not only that, but then millions of lines of code would break:

int x = 5;

foo(x); // cannot possibly change what x refers to, no matter what you think the compiler does with references.

Share this post


Link to post
Share on other sites
C++ doesn't handle objects the same way Java does... [smile] I suppose I need to clarify what I wrote above, though.

C++:

void wibble(int &foo) {
foo = 5;
// Same piece of memory, new value
}

int bar = 3;
wibble(bar); // bar is 5

void wibble(Thing &foo) {
foo = Thing();
// Still same piece of memory. A Thing is default-constructed on the stack,
// and the assignment operator is invoked. Thus the foo is changed.
}

Thing bar(args);
wibble(bar); // bar is a default Thing



Java:

public void wibble(int foo) {
foo = 5;
// foo was passed by value.
}

int bar = 3;
wibble(bar); // bar is still 3.

public void wibble(Thing foo) {
foo.member = 3; // This change *is* seen because it affects object *contents*
foo = new Thing();
// foo was an object reference passed by value, so only the local variable
// points at the new Thing.
}
// The new Thing no longer has any references and will be GCd eventually.

Thing bar(args);
wibble(bar); // bar is still the same Thing, but its .member has changed.



Share this post


Link to post
Share on other sites
Quote:
Original post by Xai
BUT EVEN ON VISUAL C++ 6 this was a compiler setting you could set EITHER WAY - its just that the correct way didn't work with windows, because the windows API had code counting on the old way ...


I have never seen a compiler setting for for-loop scope on Visual C++ 6. Is it command line only?

Share this post


Link to post
Share on other sites

This topic is 4733 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this