2

I'm new to C++ and i have a little experience with C and different dynamic scripting languages, such as JavaScript, PHP, and a little Ruby and Python. I've worked, even if not for long, with Object Oriented (OO) principles, but the thing that is new to me is that C++ does use pointers to classes. Pointers in C are not a mystery for me anymore (I hope so at least) and if I get it right - never use pointers except you have no other option. Exceptions would be if you want to keep track of a special variable or if you want to pass it to a function to change its value. And since I have to have a motivation to use pointers which one could I have to use them in C++. Could you please refer to an example? I have studied on Wikipedia. It is an example of a Builder Design Pattern in C++. They use Pizza class and PizzaBuilder, which uses a m_pizza pointer to Pizza class. What is the Reason to use a pointer instead of an normal instance here?

Edit:

Just to avoid misconceptions

  • What I meant with my statement: "Pointers in C are not a mystery for me anymore", is that I know how they stored in memory etc. It does not mean I'm a C-ninja :)

  • And when i say: "I've worked, even if not for long, with Object Oriented (OO) principles", I mean not for long as if not very experienced but I get it at the first glance, and I worked only with high-level scripting languages and had no experience with any other low-level languages except for C and C has no classes. :)

Crowman
  • 25,242
  • 5
  • 48
  • 56
orustammanapov
  • 1,792
  • 5
  • 25
  • 44
  • 5
    *"Pointers in C is not a mystery for me anymore( i hope so at least ) and if i get it right - never use pointers except you have no other option"* I fear you got it wrong - I wonder how you can do any serious piece of software in C without using pointers. Any time you have the need to use dynamic memory (`malloc`) you have to use pointers. In C++ you can reduce *explicit* dynamic memory management using standard library containers, but as soon as you allocate one of them with `new` you have to deal with pointers. – LorenzoDonati4Ukraine-OnStrike Sep 01 '13 at 10:21
  • 2
    There are no 'class pointers' in C++, as C++ classes are not objects. There are however *object* pointers. Is that what you're referring to? – user207421 Sep 01 '13 at 10:32
  • 2
    Let me add that you probably have not really grasped the principles of object oriented programming (OOP) either. Because in OOP, objects need to communicate with each other, frequently with objects they did not create themselves. And passing around pointers to these objects is the only way to do this. Even such languages like Java use pointers all the time, even though they try to hide them under the hood. Actually, C++ is unique in the way it actually allows you to create objects that are not dynamically allocated; but even for these instances, method calls implicitely pass a this pointer! – cmaster - reinstate monica Sep 01 '13 at 10:36
  • @LorenzoDonati I never said that i have created any serious software piece, but i'm willing to that is why i'm learning. i have never studied programming, everything i have learned so far i learned myself. Maybe i put it wrong saying i it is not a mystery for me anymore, what i really meant was that i understand how pointers stored in memory. I get it how it works in `C` as i stated above, i could even emulate OOP, having pointer storing reference to all needed code, what i meant according to example why is it used there? couldn't i just use normal class??? – orustammanapov Sep 01 '13 at 10:36
  • A good understanding of pointers is fundamental to working with C++. A good starting point might be to get one of the introductory C++ books listed [in this question](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Matthew Strawbridge Sep 01 '13 at 10:40
  • @cmaster it is very interesting. as i said the only OOP languages i had experiences with are scripting languages. i saw the reason of using classes as a way storing large amounts of code in the human readable and easier to use way. i get that it more efficient to point to the same memory location but isn't it against polymorphism? Where you have multiple instances with different property values? and if it is possible how can i make use of pointers that way. thanks in advance:) – orustammanapov Sep 01 '13 at 10:44
  • @EJP Ooo, yes you actually right, that is what i meant. And what would be the motivation to use one? – orustammanapov Sep 01 '13 at 10:46
  • 1
    Keep in mind that although the general principles of OOP are not that different when applied to different languages, the details and the specific idioms may be largely different (and I'm not talking only of syntax, but semantics too). This is especially true for C++ compared to scripting languages. My advice is that you should master the basics of C++ very well before you try to understand general abstract concepts as design patterns using C++ as a basis. – LorenzoDonati4Ukraine-OnStrike Sep 01 '13 at 11:02
  • Moreover try not to confuse yourself with C: most people believe that C++ is more or less a superset of C, but this is not true. Even basic things may be different between C and C++. The common syntax may hide nasty surprises for the unaware. If you want to learn C++ stick with it and don't mix it with C until you get much more experienced. – LorenzoDonati4Ukraine-OnStrike Sep 01 '13 at 11:07
  • @LorenzoDonati thanks for advice, but i think the best way to learn is to get right into action:), i don't create any code that would be used in a real project to harm anyone though. BUT what advantage would i have to keep track of that Pizza class?? Why create additional pointers if you need only the data(its methods etc.)? Or am i reading the code wrong. I'm new to `C++` as i said already, it is possible that i get it wrong... – orustammanapov Sep 01 '13 at 11:10
  • Concerning your comment about pointers being against polymorphism: If you don't have a pointer, you and the compiler know the exact type of an object, hence no runtime decision is even necessary. The point about polymorphism is that you can talk about an instance as if it were an instance of its super class, and that method calls are dispatched at _runtime_ to the correct class. And that generally requires use of pointers, because otherwise you would never be in a situation where you don't know the exact class of an instance at _compile_ time. – cmaster - reinstate monica Sep 01 '13 at 11:23
  • @LorenzoDonati For learing OOP, C++ is among the worst languages there is. First, because of its mind boggling complexity and its many technical details, and second, because so much code uses compile time decisions through templates (which has nothing to do with OOP). The best language I know for _really_ learning OOP, is ObjectiveC. – cmaster - reinstate monica Sep 01 '13 at 11:29
  • @cmaster I completely agree with you about C++ being a bad choice to learn OOP. I don't know Objective-C, but from my past experience I would advice Java: it is robust, lots of good documentation targeted also at beginners, lots of safety nets, lots of libraries that "just work". Alas I admit it is rather verbose and not too much fun to write and read :-), but a good IDE helps there. Ah, and of course not the faster horse (but a beginner shouldn't care). – LorenzoDonati4Ukraine-OnStrike Sep 01 '13 at 11:42
  • @LorenzoDonati ObjectiveC has its main characteristics that it is dynamically typed, all method calls are dispatched at runtime. You have static types, but they are for error checking only. Which makes it feel like an OO language should. You also have built-in reference counting, and you write method calls like this: `[myDictionary setObject:someObject forKey:@"key"]` - there is hardly anything more readable than ObjectiveC code. It's really a very flexible, very explicit, and very fun to use language. Pity, it's pretty much Apple only :-( – cmaster - reinstate monica Sep 01 '13 at 12:01

2 Answers2

3

The reason they use pointers in this example is that its an abstract factory. Its purpose is to build pizza objects from different pizza classes.

The abstract factory needs to hold these objects without knowing how much space they take in memory. That's why you can't use plain instances as member variables here. Their size would differ with every implementation of the pizza builder.

Well i think that's the idea here anyway. In this example they always use the same class for pizza, but you could implement a factory that produces pizzas with whole different features by deriving from the base pizza. And then you need a pointer in the abstract pizza builder to hold the pizza.

dsu
  • 81
  • 4
  • So, the abstract classes hold a reference to the same Pizza in memory? That is the way they spare extra space they would've used if they've used a normal instance, am i get it right so far? So, every time new abstract class will implemented they end up rewriting the memory location the Pizza pointer referring to, right? And the `constructPizza` method makes sure the memory location have new property values with a new `PizzaBuilder` implementation? am i right? – orustammanapov Sep 01 '13 at 11:36
  • 1
    Abstract classes are base classes that can not be instantiated. They have at least one pure virtual method (think of them like signatures that need to be implemented in concrete derived classes). Remember that every derived class is of the abstract type "Pizza" too, so you can give a Pizza pointer to those objects no matter what the derived class is (doing upcasting). This is helpful if your derived classes are polymorphic.About polymorphism, see on wiki: http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29 – Nick Louloudakis Sep 01 '13 at 11:49
  • Well the point is that you are able to create different kinds ( derived classes ) of pizzas. imagine a pizza that has a filling and a topping. you will need at least one extra member to hold the topping in a class FilledPizza that is derived from pizza. the abstract factory can hold that pizza too, even though it is not a "standard" Pizza object. but the filled pizza is of a different size than the standard pizza. that's why it is allocated on the heap and stored with a pointer. i think i can't explain it any better. anyone else? – dsu Sep 01 '13 at 12:03
  • @dsu when you write about abstract factory do you mean builder? i'm not really familiar with abstract factory and i don't know how it differs from a builder class. And what i'm concerned about is the memory. I have to apologize for asking you again, but did they use the pointer to pizza in PizzaBuilder so that all derived classes such as Hawaiian- and SpicyPizzaBuilder point to the same object? In that case every implementation of a derived class overwrites the previous values..? – orustammanapov Sep 01 '13 at 12:22
  • @orustammanapov Please read and search about Design Patterns. See here for more: http://en.wikipedia.org/wiki/Software_design_pattern - Factory is a design pattern for creating objects without specifying the exact class type the object will be created. See more on this here: http://en.wikipedia.org/wiki/Factory_method_pattern – Nick Louloudakis Sep 01 '13 at 12:26
  • @NickL Guys i really appreciate your will to help, but every time i get a comment i get frustrated because i have a feeling nobody reads what i write. I don't want get confused even more, i have a question about memory and about one way being better than the other, design patterns are of any concern if they are applicable at the example i'm referring to. example is about a builder pattern, so how does the abstract factory pattern relates to my question, if only possible please try to avoid mixing stuff that could be dropped or explained differently. and thanks for the links. – orustammanapov Sep 01 '13 at 12:39
  • 1
    @orustammanapov I apologize for misunderstanding your question, I will try to answer about memory. The "m_pizza = new Pizza;" allocates memory and makes the pointer-member variable "m_pizza" to point to it. By using getPizza(), you are getting that pointer to the object's allocated memory. Notice that if we have 2 consequent calls of same builder's instance createNewPizzaProduct() here, 2 objects will be created, but only the last one's memory will be set to be pointed by member variable pointer, causing a memory leak. Different builders also put values on their own m_pizza var. instances. – Nick Louloudakis Sep 01 '13 at 12:57
  • Also, about the difference of Builder and Factory, please look here: http://stackoverflow.com/questions/757743/what-is-the-difference-between-builder-design-pattern-and-factory-design-pattern – Nick Louloudakis Sep 01 '13 at 13:08
  • @NickL. Great answer, thanks! Are you sure about memory leak? doesn't the pointer stored in the **hawaiian** and **spicy** variables by calling `cook.getPizza()` programmer returning the Pizza pointer, which he deletes later, and he does it before the next `createNewPizzaProduct()` call? i may get it wrong though, just curious..:) And could write it as an answer please, so that i could accept it. thanks again. – orustammanapov Sep 01 '13 at 13:19
  • 1
    The way it is called in the example is not causing a memory leak. But if for example he did a call of m_pizzaBuilder->createNewPizzaProduct(); in the Cook's constructPizza() class for 2 times (maybe of a mistake for example), there would probably be one. My point is not that the code is leaked (I think it does not, in this example), but that it is not secured for possible memory leaks. – Nick Louloudakis Sep 01 '13 at 13:30
1

The m_pizza = new Pizza; line in the constructPizza() method allocates memory and makes the pointer-member variable "m_pizza" to point to it. By using getPizza(), you are getting that pointer to the object's allocated memory.

Apart from that, each builder object created has its own Pizza pointer member variable. Therefore, in main, Pizza objects pointed by hawaiian and spicy after each getPizza() invoke, are different objects.

Additionally, please notice that if we have 2 consequent calls of same builder's instance createNewPizzaProduct() somewhere, 2 objects will be created, but only the last one's memory will be set to be pointed by member variable pointer, causing a memory leak. (This could happen for example if m_pizzaBuilder->createNewPizzaProduct(); is called 2 times in Cook's constructPizza() method by mistake. My point is that the code here could be more memory-leak secure, although it does not seem to have any leaks the way it is written).

Nick Louloudakis
  • 5,856
  • 4
  • 41
  • 54