The worst things about C++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • bjarne

    #61
    Re: The worst things about C++


    Steven T. Hatton wrote:
    bjarne wrote:
    >
    Steven T. Hatton wrote:
    >
    You would have to be insane to learn C++ by reading Stroustrup's book!
    You seem remarkably certain of your opinion. As far as I can tell
    >
    It was a joke: "Trust me, I did it that way. ;) "
    Sorry to misread the "wink".

    >
    (1) there is no one best way to learn C++ for all people
    (2) there is no one best book for learning C++ for all people
    (3) many people have successfully learned C++ from TC++PL
    (4) many people have successfully learned C++ from other sources
    (5) many people have failed to learn C++ from TC++PL
    (6) many people have failed to learn C++ from other sources

    Here, "many" means "hundreds of thousands".
    >
    What I find is that reading a different introductory text usually gives me a
    new perspective on things.
    It is always a good idea to get two views on something.

    In http://www.research.att.com/~bs/bs_faq.html#best-book I give my
    opinion on who might benefit from TC++PL: "The book is aimed at
    programmers with some experience and a wish to master C++. It is not
    aimed at non-programmers trying to learn their first programming
    language or casual programmers trying to gain a superficial
    understanding of C++ as fast as possible."

    To each his/her own. People really do think and learn differently.
    People really do have different interests, skills, and needs when it
    comes to writing code.
    >
    I could not agree with you more. I know my learning style is quite
    different from that of most other people. I quite enjoyed TC++PL(SE), and
    plan to read it again. I consider it among the great works of the 20th
    Century.
    Thanks.

    Though I never finished it, I rather enjoyed this as well:
    http://www.hkbu.edu.hk/~ppp/cpr/toc.html
    You might find his "Prolegomen a" easier to start with.

    -- Bjarne Stroustrup; http:/www.research.at t.com/~bs

    Comment

    • Noah Roberts

      #62
      Re: The worst things about C++


      peter koch wrote:
      Steven T. Hatton skrev:
      peter koch wrote:
      inline template <typename T>
      T min(T const& i, T const& j) { return i < j? i: j; }
      >
      (This last step will probably be taken immediately if you are anything
      than a beginning C++-programmer).
      See page 59 of _C++ Templates: The Complete Guide_ for s discussion of
      problems related to using const references.
      I do not have that book: if you believe there to be problems with const
      references in my example, please feel free to speak up.
      The problem has to do with how character arrays get resolved per
      reference vs. value. For example you wouldn't be able to pass two
      string literals of different length to that function:

      char * x = min("hello", "hell");

      Nope...won't work (not according to the book anyway).

      Reason, becasue it is reference semantics it attempts to pass char[6]&
      as first and char[5]& as second parameters...ca n't happen.

      The way to fix this is to override for char*, which you have to do
      anyway:

      template<>
      char* min<char*>(char * l, char* r) { ... do strcmp stuff...}

      So, there is no "problem" to speak of, just something to be aware of.

      Comment

      • Steven T. Hatton

        #63
        Re: The worst things about C++

        bjarne wrote:
        >
        Steven T. Hatton wrote:
        [...]
        It is always a good idea to get two views on something.
        My preference is that alternative views are mutually consistent. Especially
        when they are from the same source. Perhaps the failing is in me, but I
        cannot reconcile these two paragraphs from the Standard:

        <quote>
        §3.3/4[Note: these restrictions apply to the declarative region into which a
        name is introduced, which is not necessarily the same as the region in
        which the declaration occurs. In particular, elaborated-type-specifiers
        (3.3.1) and friend declarations (11.4) may introduce a (possibly not
        visible) name into an enclosing namespace; these restrictions apply to that
        region. Local extern declarations (3.5) may introduce a name into the
        declarative region where the declaration appears and also introduce a
        (possibly not visible) name into an enclosing namespace; these restrictions
        apply to both regions. ]

        §3.3.1/6[Note: friend declarations refer to functions or classes that are
        members of the nearest enclosing namespace, but they do not introduce new
        names into that namespace (7.3.1.2). Function declarations at block scope
        and object declarations with the extern specifier at block scope refer to
        delarations[sic] that are members of an enclosing namespace, but they do
        not introduce new names into that scope. ]
        </quote>

        I assume that if you wrote either of the above two paragraphs, it was the
        latter. At least so much as `friend' and `namespace' are involved.
        >
        >Though I never finished it, I rather enjoyed this as well:
        >http://www.hkbu.edu.hk/~ppp/cpr/toc.html
        >
        You might find his "Prolegomen a" easier to start with.
        Thanks for the pointer. It certainly looks like a good place to get an
        overview of Kant's thinking.
        --
        NOUN:1. Money or property bequeathed to another by will. 2. Something handed
        down from an ancestor or a predecessor or from the past: a legacy of
        religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
        from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/

        Comment

        • bjarne

          #64
          Re: The worst things about C++


          Steven T. Hatton wrote:
          >
          My preference is that alternative views are mutually consistent. Especially
          when they are from the same source. Perhaps the failing is in me, but I
          cannot reconcile these two paragraphs from the Standard:
          >
          <quote>
          §3.3/4[Note: these restrictions apply to the declarative region into which a
          name is introduced, which is not necessarily the same as the region in
          which the declaration occurs. In particular, elaborated-type-specifiers
          (3.3.1) and friend declarations (11.4) may introduce a (possibly not
          visible) name into an enclosing namespace; these restrictions apply to that
          region. Local extern declarations (3.5) may introduce a name into the
          declarative region where the declaration appears and also introduce a
          (possibly not visible) name into an enclosing namespace; these restrictions
          apply to both regions. ]
          >
          §3.3.1/6[Note: friend declarations refer to functions or classes that are
          members of the nearest enclosing namespace, but they do not introduce new
          names into that namespace (7.3.1.2). Function declarations at block scope
          and object declarations with the extern specifier at block scope refer to
          delarations[sic] that are members of an enclosing namespace, but they do
          not introduce new names into that scope. ]
          </quote>
          >
          I assume that if you wrote either of the above two paragraphs, it was the
          latter. At least so much as `friend' and `namespace' are involved.
          >
          In the old days, the names of friends were injected into the enclosings
          scope. That caused a variety of problems. Not injecting made friends
          useless. The solution was to make the names of friends mach
          declarations in enclosing scopes but otherwise to otherwise make
          functions inaccessible ("invisible" ). This is hard to say briefly and
          precisely.

          My reading of the two paragraphs is that they use different words to
          express the idea that the function names are there in the enclosing
          scopes in a way so that they are not seen unless they are used just
          right.

          Yes, I know that what I just said is also vague, but I'm trying to
          convey an idea, not to define a mechanism. Consider this simplified
          example from 7.3.1.2 Namespace member definitions:

          namespace A {
          class X {
          friend void f(X); // A::f(X) is a friend
          };

          // A::f is not visible here (so f is not "injected" into A)

          X x;
          void f(X) { /* ... */} // definition of A::f

          // A::f is visible here and known to be friends (so f was "known
          to be" in A or we couldn't have connected the friend declaration to the
          definition)
          }

          Comment

          • Steven T. Hatton

            #65
            Re: The worst things about C++

            bjarne wrote:
            >
            Steven T. Hatton wrote:
            >>
            >My preference is that alternative views are mutually consistent.
            >Especially
            >when they are from the same source. Perhaps the failing is in me, but I
            >cannot reconcile these two paragraphs from the Standard:
            >>
            ><quote>
            >§3.3/4[Note: these restrictions apply to the declarative region into
            >which a name is introduced, which is not necessarily the same as the
            >region in which the declaration occurs. In particular,
            >elaborated-type-specifiers (3.3.1) and friend declarations (11.4) may
            >introduce a (possibly not visible) name into an enclosing namespace;
            >these restrictions apply to that region. Local extern declarations (3.5)
            >may introduce a name into the declarative region where the declaration
            >appears and also introduce a (possibly not visible) name into an
            >enclosing namespace; these restrictions apply to both regions. ]
            >>
            >§3.3.1/6[Note: friend declarations refer to functions or classes that are
            >members of the nearest enclosing namespace, but they do not introduce new
            >names into that namespace (7.3.1.2). Function declarations at block scope
            >and object declarations with the extern specifier at block scope refer to
            >delarations[sic] that are members of an enclosing namespace, but they do
            >not introduce new names into that scope. ]
            ></quote>
            >>
            >I assume that if you wrote either of the above two paragraphs, it was the
            >latter. At least so much as `friend' and `namespace' are involved.
            >>
            >
            In the old days, the names of friends were injected into the enclosings
            scope. That caused a variety of problems. Not injecting made friends
            useless. The solution was to make the names of friends mach
            declarations in enclosing scopes but otherwise to otherwise make
            functions inaccessible ("invisible" ). This is hard to say briefly and
            precisely.
            The biggest problem in trying to understand the intent is that terms are
            being used in ways which are not consistent with definitions provided
            within the Standard. It seems likely that names which are first declared
            (and not defined) as friends are given a unique status, only shared by
            other names introduced by non-defining friend declarations. Unfortunately
            there is no special term used to denote that status. Instead terms such
            as "visible" which have a specific definition (which in the case of visible
            includes being the antonym of "hidden") are used in ways inconsistent with
            their definitions.
            My reading of the two paragraphs is that they use different words to
            express the idea that the function names are there in the enclosing
            scopes in a way so that they are not seen unless they are used just
            right.
            >
            Yes, I know that what I just said is also vague, but I'm trying to
            convey an idea, not to define a mechanism. Consider this simplified
            example from 7.3.1.2 Namespace member definitions:
            >
            namespace A {
            class X {
            friend void f(X); // A::f(X) is a friend
            };
            >
            // A::f is not visible here (so f is not "injected" into A)
            >
            X x;
            void f(X) { /* ... */} // definition of A::f
            >
            // A::f is visible here and known to be friends (so f was "known
            to be" in A or we couldn't have connected the friend declaration to the
            definition)
            }
            My understanding is that a matching function signature with a different
            return type will lead to an ambiguity (or other conflict) error if it is
            visible in the immediate enclosing namespace of the friend declaration.
            It's still not clear to me whether f() might be found through ADL, and if
            so, whether it becomes a member of A. For example:

            namespace A { class X; }
            namespace Z {
            void f(A::X);//forward declaration
            }
            namespace A {
            class X {
            friend void f(X); // should this refer to Z::f(A::X)?
            };
            }

            namespace Z {
            void f(A::X){/*define here*/}
            }

            namespace A {
            //Can Z::f(A::X) be used here without qualification or further definition?
            //If f(X) can be used here, is it a member of A?
            }


            --
            NOUN:1. Money or property bequeathed to another by will. 2. Something handed
            down from an ancestor or a predecessor or from the past: a legacy of
            religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
            from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/

            Comment

            • Steven T. Hatton

              #66
              Re: The worst things about C++

              Steven T. Hatton wrote:
              bjarne wrote:
              >
              >>
              >Steven T. Hatton wrote:
              >>>
              >>My preference is that alternative views are mutually consistent.
              >>Especially
              >>when they are from the same source. Perhaps the failing is in me, but I
              >>cannot reconcile these two paragraphs from the Standard:
              >>>
              >><quote>
              >>§3.3/4[Note: these restrictions apply to the declarative region into
              >>which a name is introduced, which is not necessarily the same as the
              >>region in which the declaration occurs. In particular,
              >>elaborated-type-specifiers (3.3.1) and friend declarations (11.4) may
              >>introduce a (possibly not visible) name into an enclosing namespace;
              >>these restrictions apply to that region. Local extern declarations (3.5)
              >>may introduce a name into the declarative region where the declaration
              >>appears and also introduce a (possibly not visible) name into an
              >>enclosing namespace; these restrictions apply to both regions. ]
              >>>
              >>§3.3.1/6[Note: friend declarations refer to functions or classes that
              >>are members of the nearest enclosing namespace, but they do not
              >>introduce new names into that namespace (7.3.1.2). Function declarations
              >>at block scope and object declarations with the extern specifier at
              >>block scope refer to delarations[sic] that are members of an enclosing
              >>namespace, but they do not introduce new names into that scope. ]
              >></quote>
              >>>
              >>I assume that if you wrote either of the above two paragraphs, it was
              >>the
              >>latter. At least so much as `friend' and `namespace' are involved.
              >>>
              >>
              >In the old days, the names of friends were injected into the enclosings
              >scope. That caused a variety of problems. Not injecting made friends
              >useless. The solution was to make the names of friends mach
              >declarations in enclosing scopes but otherwise to otherwise make
              >functions inaccessible ("invisible" ). This is hard to say briefly and
              >precisely.
              >
              The biggest problem in trying to understand the intent is that terms are
              being used in ways which are not consistent with definitions provided
              within the Standard. It seems likely that names which are first declared
              (and not defined) as friends are given a unique status, only shared by
              other names introduced by non-defining friend declarations. Unfortunately
              there is no special term used to denote that status. Instead terms such
              as "visible" which have a specific definition (which in the case of
              visible includes being the antonym of "hidden") are used in ways
              inconsistent with their definitions.
              >
              >My reading of the two paragraphs is that they use different words to
              >express the idea that the function names are there in the enclosing
              >scopes in a way so that they are not seen unless they are used just
              >right.
              >>
              >Yes, I know that what I just said is also vague, but I'm trying to
              >convey an idea, not to define a mechanism. Consider this simplified
              >example from 7.3.1.2 Namespace member definitions:
              >>
              > namespace A {
              > class X {
              > friend void f(X); // A::f(X) is a friend
              > };
              >>
              > // A::f is not visible here (so f is not "injected" into A)
              >>
              > X x;
              > void f(X) { /* ... */} // definition of A::f
              >>
              > // A::f is visible here and known to be friends (so f was "known
              >to be" in A or we couldn't have connected the friend declaration to the
              >definition)
              >}
              >
              My understanding is that a matching function signature with a different
              return type will lead to an ambiguity (or other conflict) error if it is
              visible in the immediate enclosing namespace of the friend declaration.
              It's still not clear to me whether f() might be found through ADL, and if
              so, whether it becomes a member of A. For example:
              >
              namespace A { class X; }
              namespace Z {
              void f(A::X);//forward declaration
              }
              namespace A {
              class X {
              friend void f(X); // should this refer to Z::f(A::X)?
              };
              }
              >
              namespace Z {
              void f(A::X){/*define here*/}
              }
              >
              namespace A {
              //Can Z::f(A::X) be used here without qualification or further
              definition? //If f(X) can be used here, is it a member of A?
              }
              >
              >
              I should have waited until I got some sleep. I knew there was something
              wrong with what I was thinking. I now recall what the error is. A
              function is not looked up using ADL until it is called. I was thinking it
              might be looked up when it was declared.

              Now I have to go and think about how that impacts the proposed code shown
              above.
              --
              NOUN:1. Money or property bequeathed to another by will. 2. Something handed
              down from an ancestor or a predecessor or from the past: a legacy of
              religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
              from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/

              Comment

              • wkaras@yahoo.com

                #67
                Re: The worst things about C++


                bjarne wrote:
                ....
                (5) many people have failed to learn C++ from TC++PL
                (6) many people have failed to learn C++ from other sources
                >
                Here, "many" means "hundreds of thousands".
                ....

                I hope I'm not going to hear this quoted every day in the coffee
                room for the rest of my working life.

                There are alot of programmers who feel they have failed to learn
                C++ because they don't know it as well as some other, smaller
                language (usually C). Same programmers are often recognized
                as experts in <insert-OS-of-your-choiceeven though they have
                only ever used around 20% of the OS's API.

                Alot of other programmers decide (after reading part of or
                just thumbing through a C++ book) that they do not wish to
                learn C++.

                In my own limited experience, I can't remember anyone
                with basic aptitude as a programmer who couldn't
                eventually grasp any aspect of C++ they wanted
                or needed to know. So I could not say I ever meet
                anyone who truely "failed" to learn C++.

                I first learned (or started learning) C++ from the ARM,
                which is supposed to be the worst way to do it. But
                the notes about how O-O and other language features
                could be implemented gave me confidence that the
                language was relevant to the performance-sensitive
                stuff I work on. Maybe we're relics, but alot of
                programmers don't feel comfortable writing code
                that they don't feel they could "manually compile"
                into assembler. I haven't seen any C++ books
                that do a good job of presenting contemporary C++
                to programmers with this point of view.

                Comment

                • wkaras@yahoo.com

                  #68
                  Re: The worst things about C++

                  Signal9 wrote:
                  If you invest your time in this language it will not steer you wrong.
                  Honestly I would say learn this as your major language, but also learn
                  other languages. Java and C# are very popular right now and have a
                  decent mature framework.
                  If the point is to learn about programming (not to get a job) learn
                  C++, SmallTalk, one not-too-wierd assembly language, LISP
                  and maybe Prolog.

                  I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                  they're subsets of C++.

                  Comment

                  • kwikius

                    #69
                    Re: The worst things about C++


                    wka...@yahoo.co m wrote:
                    I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                    they're subsets of C++.
                    Nope. they both have automated garbage collection.

                    regards
                    Andy Little

                    Comment

                    • peter koch

                      #70
                      Re: The worst things about C++


                      kwikius skrev:
                      wka...@yahoo.co m wrote:
                      >
                      I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                      they're subsets of C++.
                      >
                      Nope. they both have automated garbage collection.
                      >
                      regards
                      Andy Little
                      That is not a major difference. Most C++ programs could simply attach a
                      garbage collector and forget about memory reclamaining. That does not
                      mean that they are not very different languages. I actually find very
                      few similarities between C++ and Java except from the similar syntax.

                      /Peter

                      Comment

                      • kwikius

                        #71
                        Re: The worst things about C++

                        peter koch wrote:
                        kwikius skrev:
                        wka...@yahoo.co m wrote:
                        I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                        they're subsets of C++.
                        Nope. they both have automated garbage collection.

                        regards
                        Andy Little
                        >
                        That is not a major difference. Most C++ programs could simply attach a
                        garbage collector and forget about memory reclamaining.
                        I have looked into the Boehm garbage collector, but currently I am
                        using boost::shared_p tr. I'm not sure how easy it is to detect that a
                        type has been declared on the stack, when it must work e.g with boost
                        shared pointer for example. Ideally this would be a compile time error,
                        which is possible in C++/CLI AFAICS (iow providing the choice of
                        allocation strategy). To do it in C++, the only way I can see is to set
                        up a memory pool and state that type X must be allocated from it. I can
                        then examine this pointer in the ctor (typically of a base class of
                        some users class) and throw an exception if the pointer isnt
                        referencing something in the memory pool. A compile time error would be
                        much superior though, e.g by a keyword specifying that type X ( base
                        class) must be allocated on the heap. Of course it may be possible to
                        modify the Boehm collector to do this, but it would still be a runtime
                        thing AFAICS

                        regards
                        Andy Little

                        Comment

                        • peter koch

                          #72
                          Re: The worst things about C++


                          kwikius skrev:
                          peter koch wrote:
                          kwikius skrev:
                          wka...@yahoo.co m wrote:
                          >
                          I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                          they're subsets of C++.
                          >
                          Nope. they both have automated garbage collection.
                          >
                          regards
                          Andy Little
                          That is not a major difference. Most C++ programs could simply attach a
                          garbage collector and forget about memory reclamaining.
                          >
                          I have looked into the Boehm garbage collector, but currently I am
                          using boost::shared_p tr.
                          Watch out. Shared pointer provides for proper destruction of shared,
                          dynamically allocated objects. The Boehm collector allows memory to be
                          reused, but it does not destruct objects (and rightly so in my
                          opinion).
                          I'm not sure how easy it is to detect that a
                          type has been declared on the stack, when it must work e.g with boost
                          shared pointer for example.
                          I do not see the problem - so long as you assure that there are no
                          pointers to the stacbased object when you destruct it. I do believe you
                          know that you can specify your own deleter?
                          Ideally this would be a compile time error,
                          which is possible in C++/CLI AFAICS (iow providing the choice of
                          allocation strategy).
                          I do not quite get it. So far as I know, the standard C++ way is to
                          give you a choice: you can allocate it on the stack or you can allocate
                          it dynamically. If you wish to, there are techniques to prevent a class
                          from being allocated on the stack.
                          To do it in C++, the only way I can see is to set
                          up a memory pool and state that type X must be allocated from it. I can
                          then examine this pointer in the ctor (typically of a base class of
                          some users class) and throw an exception if the pointer isnt
                          referencing something in the memory pool. A compile time error would be
                          much superior though, e.g by a keyword specifying that type X ( base
                          class) must be allocated on the heap.
                          Typically, if you require your class to be dynamically allocated, you
                          declare the constructor(s) private and create a factory function.
                          Of course it may be possible to
                          modify the Boehm collector to do this, but it would still be a runtime
                          thing AFAICS
                          The Boehm collector does nothing of that sort. It simply sits there,
                          transparantly keeping an eye on your dynamically allocated memory,
                          cleaning up as needed. You do not change your code in anyway (the
                          restrictions are few: basically you are not allowed to "hide" any
                          pointers by e.g. copying them to a file, xoring them and stuff like
                          that).
                          But I might have misunderstood you ;)

                          /Peter

                          Comment

                          • wkaras@yahoo.com

                            #73
                            Re: The worst things about C++


                            kwikius wrote:
                            wka...@yahoo.co m wrote:
                            >
                            I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                            they're subsets of C++.
                            >
                            Nope. they both have automated garbage collection.
                            Strictly speaking, you're correct that this is feature of Java/C# that
                            C++ (as typically used) lacks. But my impression is, in Java/C#, it's
                            just a convenience (and an occasional inconvenience), it doesn't
                            enable a fundamentally different style or type of programming.

                            Comment

                            • kwikius

                              #74
                              Re: The worst things about C++


                              wkaras@yahoo.co m wrote:
                              kwikius wrote:
                              wka...@yahoo.co m wrote:
                              I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                              they're subsets of C++.
                              Nope. they both have automated garbage collection.
                              >
                              Strictly speaking, you're correct that this is feature of Java/C# that
                              C++ (as typically used) lacks. But my impression is, in Java/C#, it's
                              just a convenience (and an occasional inconvenience), it doesn't
                              enable a fundamentally different style or type of programming.
                              That is arguable... Anyway, though I love C++, nevertheless there is no
                              point trying to make out the language is perfect and C++ can learn from
                              other languages too.

                              regards
                              Andy Little

                              Comment

                              • kwikius

                                #75
                                Re: The worst things about C++

                                peter koch wrote:
                                kwikius skrev:
                                peter koch wrote:
                                kwikius skrev:
                                wka...@yahoo.co m wrote:

                                I'm no expert in Java or C#, but as far as I've seen, feature-wise,
                                they're subsets of C++.

                                Nope. they both have automated garbage collection.

                                regards
                                Andy Little
                                >
                                That is not a major difference. Most C++ programs could simply attach a
                                garbage collector and forget about memory reclamaining.
                                I have looked into the Boehm garbage collector, but currently I am
                                using boost::shared_p tr.
                                Watch out. Shared pointer provides for proper destruction of shared,
                                dynamically allocated objects. The Boehm collector allows memory to be
                                reused, but it does not destruct objects (and rightly so in my
                                opinion).
                                I'm not sure how easy it is to detect that a
                                type has been declared on the stack, when it must work e.g with boost
                                shared pointer for example.
                                I do not see the problem - so long as you assure that there are no
                                pointers to the stacbased object when you destruct it. I do believe you
                                know that you can specify your own deleter?
                                Ideally this would be a compile time error,
                                which is possible in C++/CLI AFAICS (iow providing the choice of
                                allocation strategy).
                                >
                                I do not quite get it. So far as I know, the standard C++ way is to
                                give you a choice: you can allocate it on the stack or you can allocate
                                it dynamically. If you wish to, there are techniques to prevent a class
                                from being allocated on the stack.
                                FWIW I want to be able to allocate on the stack or the heap, but I also
                                wanted to be able to return a shared_ptr to an object allocated on the
                                stack or the heap. Originally I figured I couldnt allow heap allocation
                                if I allowed stack allocation and vice versa, however after
                                experimenting I came up with the following, tested with boost-1.33.1.
                                It seems to work but I'm not sure if its correct and has the
                                disadvantage of requiring a dummy member shared pointer in the class.
                                When a classs my is allocated under control of shared ptr it is
                                technically under control of two shared pointers and I don't know if
                                that is acceptable. Fails unless USE_DUMMY_SHARE D_POINTER is defined

                                #include <iostream>
                                #include <boost/shared_ptr.hpp>
                                #include <boost/enable_shared_f rom_this.hpp>

                                // MSVC specific stuff to check memory leaks
                                #if defined (_MSC_VER) && defined(_DEBUG)
                                #include <crtdbg.h>
                                #endif

                                struct null_deleter
                                {
                                void operator()(void const*) const
                                {
                                }
                                };

                                // if defined puts a dummy shared_ptr in the class
                                #define USE_DUMMY_SHARE D_POINTER

                                // class where I want to be able
                                // to get a shared_pointer to it
                                // via get_ptr function
                                struct my : boost::enable_s hared_from_this <my>
                                {
                                #ifdef USE_DUMMY_SHARE D_POINTER
                                typedef boost::shared_p tr<myptr;
                                #endif
                                ptr dummy_shared_pt r;
                                my(){
                                #ifdef USE_DUMMY_SHARE D_POINTER
                                ptr temp(this,null_ deleter());
                                dummy_shared_pt r = temp;
                                #endif
                                }

                                ptr get_ptr()
                                {
                                return shared_from_thi s();
                                }
                                };

                                int main()
                                {
                                try{
                                // try stack alloc
                                my x;

                                my::ptr px = x.get_ptr();

                                if( px.get() == &x){
                                std::cout << "ptr to x checks ok\n";
                                }
                                else {
                                std::cout << "ptr to x bad\n";
                                }

                                // try heap alloc under shared_ptr management
                                my::ptr x_ptr = my::ptr(new my());

                                my::ptr px_ptr = x_ptr->get_ptr();

                                if( px_ptr.get() == x_ptr.get()){
                                std::cout << "ptr to x_ptr checks ok\n";
                                }
                                else {
                                std::cout << "ptr to x_ptr bad\n";
                                }

                                std::cout << "no exceptions\n";
                                }
                                catch (std::exception & e){
                                std::cout << e.what() <<'\n';
                                }

                                //msvc leak checks
                                #if defined (_MSC_VER) && defined(_DEBUG)
                                #define SET_CRT_DEBUG_F IELD(a) \
                                _CrtSetDbgFlag( (a) | _CrtSetDbgFlag( _CRTDBG_REPORT_ FLAG))
                                #define CLEAR_CRT_DEBUG _FIELD(a)\
                                _CrtSetDbgFlag( ~(a) & _CrtSetDbgFlag( _CRTDBG_REPORT_ FLAG))

                                SET_CRT_DEBUG_F IELD( _CRTDBG_LEAK_CH ECK_DF );
                                #endif

                                }

                                Comment

                                Working...