Thread: Pointers and Efficiency

  1. #16
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Elysia View Post
    I don't really have much insight into auto_ptr, shared_ptr and weak_ptr, but again, I tend to handle everything myself.
    Then, with all due respect for your programming experience, you have no business talking about "modern C++".

    Near useless.
    Still nonsense. I typically use 10 times as many references as pointers, and that includes smart pointers. References are the method of passing objects around to functions that do not intend to keep them. And since you want object lifetimes to be as predictable as possible, you'll see to it that most functions have no intention of keeping their argument objects.

    They're incredibly static, not dynamic.
    They refer to the object they've been initialized with. That's a good thing. It makes them predictable. Reassigning pointers to different objects is a wonderful way of losing track of what the pointer points to.

    Must be initialized, and that is almost THE biggest flaw of them.
    They make rather poor class members, but that is their only flaw.

    I only use references when a function works with local variables and does not intend to store them in any way.
    That should be your primary use case. That should be an extremely frequent use case.

    Anyway, I take effciency before pass by value any day.
    Who's talking about pass-by-value?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    Then, with all due respect for your programming experience, you have no business talking about "modern C++".
    Modern C++, maybe not in that case, but I've managed pretty far without them.

    Still nonsense. I typically use 10 times as many references as pointers, and that includes smart pointers. References are the method of passing objects around to functions that do not intend to keep them. And since you want object lifetimes to be as predictable as possible, you'll see to it that most functions have no intention of keeping their argument objects.
    To me, that really doesn't matter. I use memory manager to keep track of when objects are in use an destroy them when they're not. Simple as that. To me, anyway.

    They refer to the object they've been initialized with. That's a good thing. It makes them predictable. Reassigning pointers to different objects is a wonderful way of losing track of what the pointer points to.
    But very inefficient. Or I suppose it could be good to have one that CAN be reassigned and one that CANNOT since there are uses for both types.

    That should be your primary use case. That should be an extremely frequent use case.
    Never has been for me. Since I use OO a lot, I need classes that keeps track of other classes, and that means pointers. When I don't need pointers, I pass by value, since they're mostly integers or enums or such.
    And in any case, that's just one case usage scenario. Where pointers can be used for many more.

    Who's talking about pass-by-value?
    The whole discussion started because I wanted pointers for class members and pointers for argument for the classes instead of passing the arguments by value and storing an extra copy of the argument type in the class

    ...But I tire of this. Everyone has their own way of coding and we should stick to that. There's really no good or bad way. What works best for you is the method you should take. And that's the good thing why the language is so flexible. You can design everything in so many ways. And you can find a way to suit you the most.

  3. #18
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Elysia View Post
    But very inefficient.
    How is it inefficient? Do you mean in this comparison?
    Code:
    object *p = get_first_object();
    // use p
    p = get_second_object();
    // use p
    vs
    Code:
    object &r1 = get_first_object();
    // use r1
    object &r2 = get_second_object();
    // use r2
    Because any compiler with even a primitive flow analysis will just reuse the same storage space for the second reference if r1 isn't used anymore after r2 is assigned. And if it is, it still works, whereas the pointer reassign snippet just misbehaves.

    Never has been for me. Since I use OO a lot, I need classes that keeps track of other classes, and that means pointers.
    I still don't see the connection to OO.

    And in any case, that's just one case usage scenario. Where pointers can be used for many more.
    That's exactly their weakness. Or rather, that's what makes them a low-level component that should be used to build high-level components (smart pointers, containers) that are then used in high-level code.

    ...But I tire of this. Everyone has their own way of coding and we should stick to that.
    If we always stick to the way we already do it, how do we get better? The nice thing about this forum is that you can discuss the relative merit of various approaches.

    There's really no good or bad way.
    There's no universal best way. There definitely are good and bad ways. For example, not using RAII and using endless try...catch blocks in an attempt to make code exception-safe would be a bad way. (Not that I'm accusing you of doing that. It's just an example that springs to mind whenever I read about raw pointers.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #19
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    How is it inefficient? Do you mean in this comparison?
    Code:
    object *p = get_first_object();
    // use p
    p = get_second_object();
    // use p
    vs
    Code:
    object &r1 = get_first_object();
    // use r1
    object &r2 = get_second_object();
    // use r2
    Because any compiler with even a primitive flow analysis will just reuse the same storage space for the second reference if r1 isn't used anymore after r2 is assigned. And if it is, it still works, whereas the pointer reassign snippet just misbehaves.
    Classes are a very good example as I outlined before. To avoid copying memory and all that, you will need pointers to store other classes. And what's the point in taking a reference to a pointer? Or when you have a pointer, why would you return a reference? If you already have a pointer, I return a pointer. Then you can do whatever with that pointer.
    It's also possible to use const pointers to protect the pointer from changing and preventing the destination from changing.
    Since I rely so heavily on many parts being objects, pointers are almost everything I use. I tend to use a memory manager too, to keep track of the objects. So I don't have to keep track of deleting the pointers.
    Pointers to an object that is NOT on the heap, I do NOT use. In that case, I use references. If it's a built-in type on the stack, I use references (unless it's a C-style string, char*).
    Yes, there are global functions I use to do some dity work like converting an int to string or vice versa, but they're just awfully few compared to the heavy use of classes, and they require pointers.
    Another point is that I tend to do a lot of memory manipulation, which requires pointers. References just won't do since they're static.

    If we always stick to the way we already do it, how do we get better? The nice thing about this forum is that you can discuss the relative merit of various approaches.
    Ah, but a good question is if it should hijack a thread from someone else? And what I suggested is that we stick to a way we know and works well for us.
    I don't rely on references, for example, nor do I rely on auto_ptr, shared_ptr or weak_ptr, because I don't need them and they don't suit my style of programming. I use a memory manager only because I want to keep track of objects and delete them when they're not in use. I don't use references because they're so weak. They don't fit what I need to do, or try to do.
    Of course, discussing is a good thing, but if I really like it this way, should I change if it works really well for me? I don't think so and that's what I'm implying. We can discuss and we can learn and we can change, but I don't think my approach of doing things this way will change because I love doing it that way and it's the best way I know, that is very simple and works very well.

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I have no problem with thread drift. This thread is five pages long - do you really still remember the original question?

    You said that references are near useless, and I challenge this assertion. They may be of little use in your programming method (which, from the description, sounds very similar to what Java programmers generally do - did I understand that correctly?), but that doesn't make it a universally true statement. And it is patently untrue in modern C++.

    Modern C++ as it is generally understood, by the way, abandons a purely object-oriented approach in favor of fully exploiting the multi-paradigm capability of C++, and especially favours the generic programming paradigm. Value-like objects (without strong identity) are more common. Semantics should be checked or at least indicated by the type system as far as possible. (My description of references and various smart pointers above is an example of this; using raw pointers for everything is the antithesis to it.)
    Multi-threading aside, the three most far-reaching language changes in C++ show this: r-value references and value moving are a sign that identity matters less; variadic templates and concepts make the type system more powerful. The auto and decltype keywords are introduced to make up the negative side effects (unwieldy types - a generic library of mine can easily generate a type that is three code lines long).
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    I have no problem with thread drift. This thread is five pages long - do you really still remember the original question?
    Alright then...

    You said that references are near useless, and I challenge this assertion. They may be of little use in your programming method (which, from the description, sounds very similar to what Java programmers generally do - did I understand that correctly?), but that doesn't make it a universally true statement. And it is patently untrue in modern C++.
    I'm not a java programmer, so I wouldn't reall know...
    But if modern C++ is as you say, then I challenge modern C++ instead

    The C++ language, to me, is a way to bring powerful power into your applications. The power is what I love of the language - to be able to manipulate raw memory, to use objects and polymorphism to do things with ease. And unfortunately, references just can't live up to that - the more powerful elements of the language.
    OO was made with good intentions and they are really handy as well. Why references simply wasn't designed to handle such is beyond me, especially since C++ was designed for OO from the beginning (AFAIK).

  7. #22
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Yes, but then you would at least attempt one copy of the class and if you keep using just references, the objects would go out of scope. References are useless things in modern C++, they're almost of no use.

    But this is a register, right? So we should be able to add objects and remove them at will, making this useless.
    This is precisely why I asked you: better and more efficient than what?

    Notice that I wrote: "one could use pass by (const) reference instead of passing pointers". That is, what I had in mind was argument passing. The use of pass by (const) reference can reduce the need to add additional levels of indirection while also alleviating the need to copy the objects passed.

    Still, if you want to bring up pointer versus reference member variables: in your Register and Car example, you have an association that can be changed. In fact, the association is composition, so the Register has ownership of the Car. Consequently, storing a reference is not the right way. On the other hand, if a Register must be associated with the same Car object for its whole lifetime, then a reference member variable would be an option. As I noted, it depends on the situation.

    Not to mention that any resources used by m_Car will be allocated and you may have to overlord or specify your own copy constructor to release any resources that Car might use before copying the new object which will probably require memory copy.
    Actually, you have to write your own copy constructor, copy assignment operator and destructor since you store a Car* with ownership of the Car object. With a Car member variable instead, the compiler generated copy constructor, copy assignment operator and destructor will work with normal copying semantics. If you do not take ownership of the object, then having a Car member variable is wrong to begin with, so any comparison of efficiency is unfair.

    Useless, since references are just like pointers - compiler will pass the address to the object and it adds more complexity, having to do &rCar too, since we can't put a reference member unless it's initialized.
    Now you have a straw man argument: you are proposing an unusual design, then claiming that references are a Bad Thing.

    The whole discussion started because I wanted pointers for class members and pointers for argument for the classes instead of passing the arguments by value and storing an extra copy of the argument type in the class
    You probably should have said so from the start. Merely stating "it's more efficient for functions to take pointers to them and create the objects on the heap to avoid hugging valueble stack space and to avoid all copying of objects forth and back, wasting precious resources and cpu time" is ambiguous. Of course, one should use smart pointers rather than raw pointers in such a case.

    The power is what I love of the language - to be able to manipulate raw memory, to use objects and polymorphism to do things with ease. And unfortunately, references just can't live up to that - the more powerful elements of the language.
    Polymorphism works with references as well, for your information.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    Actually, you have to write your own copy constructor, copy assignment operator and destructor since you store a Car* with ownership of the Car object. With a Car member variable instead, the compiler generated copy constructor, copy assignment operator and destructor will work with normal copying semantics. If you do not take ownership of the object, then having a Car member variable is wrong to begin with, so any comparison of efficiency is unfair.
    When creating the object on heap and taking a pointer, there is no need to copy the class, to make a duplicate at all. Even if you make a member variable of the class, even if the compiler genereates these functions for you, you might STILL need to overload the copy constructor since, for example, the class contains some pointers, it will just copy those pointers and not the memory it points to. And when you use other classes inside a class (such as std::string), it might be better to invoke their copy constructors to copy. I'm not sure if a default copy constructor does this or not since I never pass classes by value.

    You probably should have said so from the start. Merely stating "it's more efficient for functions to take pointers to them and create the objects on the heap to avoid hugging valueble stack space and to avoid all copying of objects forth and back, wasting precious resources and cpu time" is ambiguous. Of course, one should use smart pointers rather than raw pointers in such a case.
    Sure, use whatever "pointer type" you may deem necessary, so long as it's a pointer. That makes it efficient in terms of less overhead with no copying of the objects

    Polymorphism works with references as well, for your information.
    I'm sure they do, but references are just too limited for me to work well with, so I probably won't ever use it. I can't think of any polymorphism where I've used references either...

  9. #24
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    A default copy constructor invokes the copy constructors of contained objects, yes.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    When creating the object on heap and taking a pointer, there is no need to copy the class, to make a duplicate at all.
    I agree, but I also disagree. Whether there is any need to copy an object depends not on whether it is accessed via a pointer or an iterator, but whether there is a need to copy the object in the first place.

    Even if you make a member variable of the class, even if the compiler genereates these functions for you, you might STILL need to overload the copy constructor since, for example, the class contains some pointers, it will just copy those pointers and not the memory it points to.
    I think you misread my point: when I say Car member variable, it is as opposed to the Car* member variable.

    And when you use other classes inside a class (such as std::string), it might be better to invoke their copy constructors to copy. I'm not sure if a default copy constructor does this or not since I never pass classes by value.
    The compiler generated copy constructor would copy std::string member variables correctly. Incidentally, I never pass classes by value either, though I have passed objects by value

    I'm sure they do, but references are just too limited for me to work well with, so I probably won't ever use it.
    Out of curiosity: do you use the C++ standard library?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    I agree, but I also disagree. Whether there is any need to copy an object depends not on whether it is accessed via a pointer or an iterator, but whether there is a need to copy the object in the first place.
    If there's a need to copy an object, then you shouldn't be using a pointer in the first place IMO (not in the sense we're discussing here, at least). Pointers are used to access objects so we don't need to copy them (again IMO).
    And BTW, heck, I've never really used iterators. I use the trusted old FOR loop with 0 to whatever the end of whatever I'm iterating is. Like std::vector, I use size() to determine the end instead of iterators.

    The compiler generated copy constructor would copy std::string member variables correctly. Incidentally, I never pass classes by value either, though I have passed objects by value
    Okay, that's cool. Good compiler. Clever compiler. But it doesn't do anything about pointers.

    Out of curiosity: do you use the C++ standard library?
    I include the standard library, of course, since the C library is nowmore deprecated and removed in Visual Studio 2005. How much I use the standard library is debatable. I mostly use MFC or some trusty old C-style functions (ie fopen, fread, fwrite, fclose).
    Last edited by Elysia; 10-24-2007 at 11:54 AM.

  12. #27
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Okay, that's cool. Good compiler. Clever compiler. But it doesn't do anything about pointers.
    I believe that is by design since deep copying may not be the desired behaviour, though it usually is.

    I include the standard library, of course, since the C library is nowmore deprecated and removed in Visual Studio 2005.
    Then you should be aware that pass by reference (and in the case of I/O streams, returning a reference) is rather widely used in the standard library. One reason is... to avoid unnecessary copying.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #28
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    I believe that is by design since deep copying may not be the desired behaviour, though it usually is.
    It's dangerous not to do deep copy when having class members that are classes.

    Then you should be aware that pass by reference (and in the case of I/O streams, returning a reference) is rather widely used in the standard library. One reason is... to avoid unnecessary copying.
    Yes, I'm quite aware. And that's perfectly fine because they're local functions that take immediete data and return it, unlike many classes and polymorphism.

  14. #29
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    It's dangerous not to do deep copy when having class members that are classes.
    I would say that it is "dangerous" not to do deep copying of objects of primitive types as well. The main problem is that the class would no longer follow normal copying semantics, but C++, like C, has a tradition of not cuddling the programmer for such things, so it is unlikely that you can convince the standards committee to force deep copying for the compiler generated copy constructor and assignment operator. This is the very freedom and power that you cherish, as I recall.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #30
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by laserlight View Post
    I would say that it is "dangerous" not to do deep copying of objects of primitive types as well. The main problem is that the class would no longer follow normal copying semantics, but C++, like C, has a tradition of not cuddling the programmer for such things, so it is unlikely that you can convince the standards committee to force deep copying for the compiler generated copy constructor and assignment operator. This is the very freedom and power that you cherish, as I recall.
    Well, no, not quite. I cherish the power they've given to developers to design with, but if they're designing a safe language, shouldn't they use a safe approach to copy? If you don't like it, you can, of course, override it. Now that's power and that's what I like.
    I don't like the fact that they don't do deep copying due to the fact that it can seriously screw up your code if you don't override the copy constructor yourself to do deep copying.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Improving the efficiency..
    By aaronljx in forum C Programming
    Replies: 11
    Last Post: 12-01-2008, 10:09 AM
  2. trouble with file pointers...
    By quasigreat in forum C Programming
    Replies: 4
    Last Post: 05-19-2008, 08:12 AM
  3. Function Pointers in C
    By Gobinath in forum C Programming
    Replies: 7
    Last Post: 03-10-2005, 11:54 AM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. Question about efficiency... structures and stuff
    By rmullen3 in forum C++ Programming
    Replies: 2
    Last Post: 01-05-2002, 01:00 PM