82

I'm trying to understand the difference between procedural languages like C and object-oriented languages like C++. I've never used C++, but I've been discussing with my friends on how to differentiate the two.

I've been told C++ has object-oriented concepts as well as public and private modes for definition of variables: things C does not have. I've never had to use these for while developing programs in Visual Basic.NET: what are the benefits of these?

I've also been told that if a variable is public, it can be accessed anywhere, but it's not clear how that's different from a global variable in a language like C. It's also not clear how a private variable differs from a local variable.

Another thing I've heard is that, for security reasons, if a function needs to be accessed it should be inherited first. The use-case is that an administrator should only have as much rights as they need and not everything, but it seems a conditional would work as well:

if ( login == "admin") {
    // invoke the function
}

Why is this not ideal?

Given that there seems to be a procedural way to do everything object-oriented, why should I care about object-oriented programming?

niko
  • 2,119
  • 3
  • 22
  • 19
  • 3
    Possible duplicates: [How is C different from C++?](http://programmers.stackexchange.com/q/38942/20011) and [The limitations of non-OOP languages](http://programmers.stackexchange.com/q/60965/20011); – Caleb Nov 16 '11 at 07:00
  • 11
    [This map of programming paradigms](http://www.info.ucl.ac.be/people/PVR/paradigmsDIAGRAMeng108.pdf) may help you. – AProgrammer Nov 16 '11 at 08:11
  • 27
    +1 to counter some downvotes. If a coworker asked me such a question, I would probably have some concerns and might even downvote him (assuming there was any kind of down arrow next to him). However, this question appears to be asked by a future software engineer and it sounds like he spent some time thinking and discussing the topic before posting. I vote for helping him out rather than dismissing. – DXM Nov 16 '11 at 08:16
  • 1
    Duplicate on SO: [Purpose of private members in a class](http://stackoverflow.com/questions/2374988/purpose-of-private-members-in-a-class) – Péter Török Nov 16 '11 at 08:18
  • 16
    @DXM Excellent idea! Downvote / upvote arrows floating around coworkers... That would work wonders. – yannis Nov 16 '11 at 12:06
  • 2
    Standard counter argument: There's also an assembler way to do everything you can do in C, so why should you care about C? (Hint: It's all about raising t he level of abstraction. C++ manages to do this with out sacrificing most of C's speed. IMO that's the main reason for C++' success.) – sbi Nov 16 '11 at 15:10
  • [Amazon has all the answers to these and more questions - Head First Object Oriented Analysis and Design](http://www.amazon.com/Head-First-Object-Oriented-Analysis-Design/dp/0596008678/) these are pretty fundamental concepts and will be hard to do just to all them and all the ones that aren't mentioned that are pre-requistes to answer some of these in a stackexchange format. –  Nov 16 '11 at 18:01
  • 1
    @Yannis - you know we are half way there. Mobile devices with a camera and augmented reality apps :) – DXM Nov 16 '11 at 18:13

12 Answers12

144

All answers so far have focused on the topic of your question as stated, which is "what is the difference between c and c++". In reality, it sounds like you know what difference is, you just don't understand why you would need that difference. So then, other answers attempted to explain OO and encapsulation.

I wanted to chime in with yet another answer, because based on the details of your question, I believe you need to take several steps back.

You don't understand the purpose of C++ or OO, because to you, it seems that your application simply needs to store data. This data is stored in variables. "Why would I want to make a variable inaccessible? Now I can't access it anymore! By making everything public, or better yet global, I can read data from anywhere and there are no problems." - And you are right, based on the scale of the projects you are currently writing, there are probably not that many problems (or there are, but you just haven't become aware of them yet).

I think the fundamental question you really need to have answered is: "Why would I ever want to hide data? If I do that, I can't work with it!" And this is why:

Let's say you start a new project, you open your text editor and you start writing functions. Every time you need to store something (to remember it for later), you create a variable. To make things simpler, you make your variables global. Your first version of your app runs great. Now you start adding more features. You have more functions, certain data you stored from before needs to be read from your new code. Other variables need to be modified. You keep writing more functions. What you may have noticed (or, if not, you absolutely will notice in the future) is, as your code gets bigger, it takes you longer and longer to add the next feature. And as your code gets bigger, it becomes harder and harder to add features without breaking something that used to work. Why? Because you need to remember what all your global variables are storing and you need to remember where all of them are being modified. And you need to remember which function is okay to call in what exact order and if you call them in a different order, you might get errors because your global variables aren't quite valid yet. Have you ever run into this?

How big are your typical projects (lines of code)? Now imaging a project 5000 to 50000 times as big as yours. Also, there are multiple people working in it. How can everyone on the team remember (or even be aware of) what all those variables are doing?

What I described above is an example of perfectly coupled code. And since the dawn of time (assuming time started Jan 1, 1970), human kind has been looking for ways to avoid these problems. The way you avoid them is by splitting up your code into systems, subsystems and components and limiting how many functions have access to any piece of data. If I have 5 integers and a string that represent some kind of state, would it be easier for me to work with this state if only 5 functions set/get the values? or if 100 functions set/get these same values? Even without OO languages (i.e. C), people have been working hard on isolating data from other data and creating clean separation boundaries between different parts of the code. When the project gets to a certain size, ease of programming becomes not, "can I access variable X from function Y", but "how do I make sure ONLY functions A, B, C and no one else is touching variable X".

This is why OO concepts have been introduced and this is why they are so powerful. They allow you to hide your data from yourself and you want to do it on purpose, because the less code that sees that data, the less chance there is, that when you add the next feature, you will break something. This is the main purpose for the concepts of encapsulation and OO programming. They allow you to break our systems/subsystems down into even more granular boxes, to a point where, no matter how big the overall project is, a given set of variables may only be accessed by 50-200 lines of code and that's it! There's obviously much more to OO programming, but, in essence, this is why C++ gives you options of declaring data/functions as private, protected or public.

The second greatest idea in OO is the concept of abstraction layers. Although procedural languages can also have abstractions, in C, a programmer must make a conscious effort to create such layers, but in C++, when you declare a class, you automatically create an abstraction layer (it's still up to you whether or not this abstraction will add or remove value). You should read/research more about abstraction layers and if you have more questions, I'm sure this forum will be more than happy to answer those as well.

DXM
  • 19,932
  • 4
  • 55
  • 85
  • 5
    Great answer, seems to hit the appropriate level given the question – Carlos Nov 16 '11 at 14:36
  • 32
    +1...mostly for the, "And since the dawn of time (assuming time started Jan 1, 1970) ..." line – CaffGeek Nov 16 '11 at 15:53
  • 5
    @Chad - I was figuring that line alone should score me at least one point :) – DXM Nov 16 '11 at 18:20
  • There's a way of dealing with this problem of scale you talk about in the procedural paradigm. It's called functions. But good way of explaining the problem. – annoying_squid Apr 26 '16 at 13:57
  • @DXM - I am not sure whether I understood the answer correctly. We can achieve the same set/get functionality in Procedural Programming also. We can write set /get functions in C to modify / get the global variable. Using this method also, we are limiting the number of functions that are modifying the global variables. And even in OOP, if we use set / get methods also, we will be using these methods from outside of the object to change the values. – kadina Aug 26 '17 at 23:39
  • I fail to see how creating abstraction layers automatically, without conscious effort, can ever be considered a good thing. – clinei Feb 07 '18 at 18:55
10

Hmm...maybe it's best to back up and try to give some idea of the basic intent of object oriented programming. Much of the intent of object oriented programming is to allow the creation of abstract data types. For a really simple example with which you're undoubtedly familiar, consider a string. A string will typically have a buffer to hold the content of the string, some functions that can operate on the string (search in it, access parts of it, create substrings, etc.) It will also (at least typically) have something to keep track of the (current) length of the string, and (probably) the size of the buffer so if (for example) you increase the string's size from 1 to 1000000, it'll know when it needs more memory to hold the larger content.

Those variables (the buffer, current length and the buffer size) are private to the string itself, but they're not local to a particular function. Each string has contents of some particular length, so we need to track that content/length for that string. Conversely, the same function (e.g., to extract a substring) might operate on many different strings at different times, so that data can't be local to the individual function.

As such, we end up with some data that's private to the string, so it's only (directly) accessible to string functions. The outside world can get the length of the string using a string function, but doesn't need to know anything about the internals of the string to get it. Likewise, it might modify the string -- but again, it does so via the string functions, and only they directly modify those variables local to the string object.

As far as security goes, I'd note that while this is reasonable as an analogy, it's not how things really work. In particular, access in C++ is specifically not intended to meet the same kind of requirements as access in an operating system. An operating system is supposed to enforce the restrictions so (for example) a normal user can't do things reserved for an administrator. By contrast, access control in C++ is only intended to prevent accidents. By design, anybody who wants to can bypass them quite easily. They're on the same order as marking a file read-only so you don't accidentally delete it. If you decide to delete the file, it's trivial to change it from read-only to read-write; all setting it to read-only does is make you at least think about it a second and decide to delete the file so it won't get deleted by accident just from hitting the wrong key at the wrong time.

Jerry Coffin
  • 44,385
  • 5
  • 89
  • 162
6

OOP versus C isn't really about any of the things you've discussed. It's primarily about packaging code into areas that won't/can't unintentionally (or sometimes even intentionally) affect each other.

C lets you basically run any function from anywhere. OOP prevents that by grouping methods into classes and only allowing you to use the methods by referencing the class containing them. So, one potentially big advantage of OOP is that you're far more likely to have a better code arrangement without lots of experience to tell you that you should.

John Fisher
  • 1,795
  • 10
  • 12
  • 4
    -1. There is nothing exclusive in C that makes all functions global. You can declare any function static and thereby limit its scope to the local file. C is not different from C++, Java etc in this aspect. Also, OOP isn't about language syntax, you can write OO programs in C just fine, although they will be a bit more crude than in languages with syntax support for OO. And the contrary: you don't get OOP just because you picked a language that supports OO. Object-orientation is a _programming style_, not a language feature. –  Nov 18 '11 at 07:20
  • @Lundin: While you are technically correct, you've missed the point. OOP languages make it default behavior to behave in an OOP way. C does not. – John Fisher Nov 18 '11 at 16:14
  • 1
    There is nothing in OO languages forcing you to do that. For example, I have seen countless of obscure C++ programs without any OO worth mentioning. Similarly, if you haven't got a clue about OO but try to implement classes, heritage etc, there is about a 100% chance of creating a messed-up program. –  Nov 18 '11 at 23:36
  • @Lundin: I don't think C++ is a fair example. It is (or at least was) meant to be able to compile C programs without (much) modification. Adding classes on top doesn't make it an OOP language on the level of C# or Java, but it does enable that kind of development. – John Fisher Nov 19 '11 at 01:39
  • You can write non-OO programs in Java too, simply hack away in one huge main file... OO is _still_ not language-specific, if the programmer doesn't know about OO, no language in the world will save them. –  Nov 21 '11 at 08:00
  • @Lundin: I'm not sure what you're going after. If someone is working in Java, he/she is exposed to OOP concepts all over the place (framework, samples, tutorials, etc.) So, not having a clue about OOP would be rather unusual in a primarily OOP language. – John Fisher Nov 21 '11 at 15:57
4

A well-written class should be a little "island of trust": You can use it and assume that it does "the right thing" and that it shields you from common pitfalls. That makes a good class a building block, which is much more reusable as a bunch of functions and variables, which might work well but show you all their ugly guts, and force you to understand how they work together, how they need to be initialized etc. A good class should be like an USB plug, while the procedural solution is like a bunch of wires, chips, tin and a soldering bit.

One point that wasn't discussed in depth is the interface / implementation aspect. An interface describes the behavior, but not the realization. So a list interface describes the concept of a list and its behavior: You would expect things like add, remove and size methods. Now there are a lot of different ways to implement this list, e.g. as a linked list or using an array buffer. The power of OO programming is that by using an interface you can reason about the behavior without knowing about the implementation. Accessing internal variables or methods would destroy this abstraction, you couldn't replace one list implementation by another, and you couldn't improve an existing implementation without touching the code using the class. That's one of the main reasons why private variables and methods are needed: To protect internal details of the implementation, so the abstraction stays intact.

OO goes even one step further: E.g. for libraries you can define an interface for things that not even exist yet, and write code that works with that interface. The users can write classes implementing the interface, and use the services provided by the library. This allows a degree of flexibility that isn't possible with procedural programming.

Landei
  • 1,993
  • 1
  • 13
  • 19
  • The concept of interfaces is not unique to object-oriented languages. A bigger factor, I think, is that in non-OOP languages nearly all the functions used within a module must belong to the same global namespace. This requires that one either prefix function names to indicate what they act upon, or else have many similar-sounding methods which do entirely different things (e.g. `SetLocation` might be used to move a `Monster`, while `SetPosition` might move a `PopupWindow`, and `Move` might be used to adjust the position of a `DisplayCursor`). Trying to find the right "move" method... – supercat Jul 18 '14 at 16:10
  • ...can be made much easier if when one writes `MyMonstor->` the editor only shows a list of methods that are applicable to things of type `Monster`. If there are many dozens of different kinds of things, each of which supports about dozen operations, cutting the amount of clutter in the method lists by 90% can greatly ease productivity. – supercat Jul 18 '14 at 16:13
  • @supercat name clashing is a language issue not a non-OOP issue. On the other hand namespaces are problematic because the compiler essentially needs to rename the function automatically or mangle it. So why not just do it manually? – annoying_squid Apr 26 '16 at 14:30
  • @annoying_squid: What OOP provides is the ability to effectively use the *type* of a funciton's primary argument to select the namespace. If I have a variable `it` of type `SuperFancyWhizBang`, invoking one of `SuperFancyWhizBang`'s methods on `it` doesn't require writing out the type `SuperFancyWhizBang`; saying `it.woozle()` will direct the compiler to automatically look for `woozle` within `SuperFancyWhizBang`. – supercat Apr 26 '16 at 14:47
3

There is a way to do everything with a Turing machine, or at minimum in an assembly language for the machine code that a C or C++ program will eventually compile down to.

So the difference is not about what the code can do, but about what people can do.

People make mistakes. Lots.

OOP introduces a paradigm and a syntax that helps reduce the size and probability density of the space of possible human coding mistakes. Sometimes by making the mistake illegal for a certain class of data object (such as it's not a method declared for that object). Sometimes by making the mistake more verbose, or stylistically odd looking compared to canonical usage of the language. Sometimes by requiring an interface with far less possible inconsistant or entangled usages (public vs. private). etc.

The bigger the project, the higher the likelihood of mistakes. Which a new coder might not be exposed to if only experienced with small programs. Thus the potential puzzlement at why OOP is valuable.

hotpaw2
  • 7,938
  • 4
  • 21
  • 47
2

Your question seems more about the purpose of OOP rather than the difference. The concept in your post is Encapsulation; and encapsulation exists to support CHANGE. When other classes are accessing your internals it becomes difficult to modify them without breaking them. In OOP you provide an interface (public members) through which you allow other classes to interact with yours, and you hide your internals so that they can safely be changed.

Eoin Carroll
  • 652
  • 5
  • 12
2

No matter where I read private variables cannot be accessed whereas public variables can be then why not make public as global and private as local whats the difference? whats the real use of public and private ? please dont say it can be used by everyone, I suppose why not we use some conditions and make the calls ?

I hope you don't ever want more than one string in your application. I also hope that your local variables persist between function calls. These things might be the same in terms of accessibility but in terms of lifetime and other usage? They're absolutely not the same.

DeadMG
  • 36,794
  • 8
  • 70
  • 139
1

As many said any program, once compiled, is turned into a binary code and, as a binary string might be used to represent an integer, any program is eventually just a number. However defining the number you need could be pretty hard and that is why high level programming languages came up. Programming languages are just models of the assembly code they eventually produce. I would like to explain you the difference between procedural and OO programming by means of this very nice paper about Context Oriented Programming http://www.jot.fm/issues/issue_2008_03/article4/

as you can see from this picture, depicted in the paper, Procedural programming provides only one dimension to associate a computational unit with a name. Here, procedure calls or names are directly mapped to procedure implementations. In Figure-a calling m1 leaves no choice but the invocation of the only implementation of procedure m1.

Object-oriented programming adds another dimension for name resolution to that of procedural programming. In addition to the method or procedure name, message dispatch takes the message receiver into consideration when looking up a method. In Figure-b we see two implementations of method m1. The selection of the appropriate method not only depends on the the message name m1, but also the receiver of the actual message, here Ry.

This indeed allows encapsulation and modularization.

enter image description here

Figure-c is finally about subject-oriented programming extends object-oriented method dispatch by yet another dimension.

Hope this helped you thinking at OOP from a different perspective.

Adam Lear
  • 31,939
  • 8
  • 101
  • 125
0

(+1) Asking a question of something you don't understand, its good, even if it sounds silly.

The difference is Object & Class Oriented Programming. "Plain C", works with data & functions. "C++" adds "object & classes" concepts, plus several related secondary concepts.

However, I advocate developers to learn "Plain C" before "C++". Or "Procedural Pascal" before "Object Pascal".

Many developers think students should be teach only one stuff.

For example, old teachers that doesn't get O.O., and teach only "Plain Structured C".

Or "hipster" teachers that teach only O.O., but not "Plain C", because "you don't need it". Or both, without caring about the teaching order.

I rather think, students should be taught both the "Structured Plain C" and "Object Oriented C (C++)". With "Plain C", first, and "C++", later.

In real world, you need to learn both paradigms (plus other paradigms, like "functional").

Thinking structured programs as a big, singleton "object", may help.

You also should put emphasis in namespaces ("modules"), in both languages, many teachers just ignore it, but, its important.

umlcat
  • 2,146
  • 11
  • 16
  • Namespaces and overloads only makes the program harder to understand. It makes the identification process context sensitive. When you see `foo()` in C++, it can be a global function, a function in the current namespace, a function in the namespace you use with `using`, a method, an inherited method and if it's in the function call: it can be in a namespace that can be resolved by argument based name lookup, and the similar is true for Java and C#. In C it can only be a static function in the current source file, or one from a header. – Calmarius Aug 30 '12 at 14:53
  • Writing MODULE_Foo() everywhere might be a visual clutter, but at least you exactly know which function it is. – Calmarius Aug 30 '12 at 14:54
  • @Calmarius the solution, clearly, is to not name anything *foo*. –  Nov 02 '17 at 16:22
0

In one word, project management. What I mean is that C++ helps me enforce rules of how my code is used by others. Working on a 5.5 million lines project I find object oriented programming very helpful. Another advantage is the compiler that makes me (and everybody else) follow certain rules and catch minor errors in compile time. All the theoretical advantages are there as well but I just wanted to focus on everyday practical things. After all it all compiles into machine code.

Gus
  • 368
  • 1
  • 4
-1

Object Oriented Programming is Procedural Programming, with boxes.

In PP, you have one box, one state, that becomes incredibly large as the project grows, causing side-effects to appear every time you forget a tiny bit of that large state.

In OO, you have many boxes, many states, and as the project grows, the boxes grow a little, and the number of boxes grows a lot.

It remains easier to look at smaller boxes, easy to have the illusion of a whole picture, but actually almost impossible, as looking at classes and interfaces hides the implementation details that can have important ramifications.

In functional programming, you have many function boxes, and decide that every function has one entry (parameters) and one exit (returns), with strictly no other access to the outside context.

Because there is no state and no side-effects (by design), you can safely analyze any function separately from the whole and know 100% how it will behave in any circumstance.

Because you are boxing code by logical units which represent actions, it also becomes possible to only have one box per typical action.

This will shrink the code of any large scale project by a huge factor compared to OOP which promotes hiding multiple analog functions all over the code base in different classes.

This will also beat PP by very far because you can grow the project for much longer since there is no more XXXXXXXL state to keep track of.

In summary, PP is probably the simplest way to approach a simple program and FP is probably the simplest way to approach a complex one.

If you factor in the goal of unifying all code bases and improving code reuse, FP should always be used, as it's the only paradigm that makes sense at a very large scale, as well as the only paradigm that has 100% reusability (you can simply copy paste a function and use it somewhere else, with no overhead whatsoever).

And you get 100% reliable unit testing for free.

And you don't have to write "private static final of_doom genius awesome string_1".

And you get parallelism for free.

Morg.
  • 250
  • 1
  • 5
-3

The simple one sentence difference is that C++ is C with Classes.(though it is much more now) I don't why you don't want to learn the differences between two by reading a great article on C++ at Wikipedia.....This article will help you a great deal :- C++ (Wikipedia)

Also googling on the issue will help. Asking random persons to explain this might be tricky. IMHO, one understands better by reading than asking someone

Pankaj Upadhyay
  • 5,060
  • 11
  • 44
  • 60
  • I have read those but they just said where they are used but still not solved my question . – niko Nov 16 '11 at 06:10
  • I did not ask the question without putting any efforts i googled but still unable to understand the difference so i met with stackoverflow to help me with these – niko Nov 16 '11 at 06:11
  • 1
    @niko , You are getting me wrong here. What i meant was that you should try to understand the difference between the two by reading. Asking your friends isn't good. Because they will provide their own understanding which might not satisy you. But, don't worry, there are great peers here, they will surely help you out :-) – Pankaj Upadhyay Nov 16 '11 at 06:18
  • Two upvotes and two donwvotes..... :-P .... Why the downvote ???? – Pankaj Upadhyay Nov 16 '11 at 07:50
  • 2
    I didn't downvote, but was sorely tempted at "C++ is C with Classes". Those of us who can actually do C++ work our asses off trying to get that *out* of people's head. – DeadMG Nov 16 '11 at 10:48
  • @DeadMG, mate I thought you didnt read the text in brackets, I second your opinion, but was just trying to explain in plain language...Also, you can refer to the history books which says **" Originally named C with Classes, the language was later renamed C++ in 1983" – Pankaj Upadhyay Nov 16 '11 at 11:07
  • 1
    @Pankaj: That's right. It *was* C with Classes. It is most definitely not C with Classes anymore, and calling it such is nearly 30 years out of date. C++ has gone a very long way since then. People who code C++ now never, ever refer to it that way. It encourages the worst habits and the wrong impression. – DeadMG Nov 16 '11 at 12:31