implicit constructor declaration (user annoyed)

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

    implicit constructor declaration (user annoyed)

    If there is at least one user-defined constructor, no constructors are
    implicitly declared.

    struct my_vec : public vector<int> {
    double foo;
    my_vec(size_t n) : vector<int>(2*n ) {}
    // oops, no default ctor any more
    // have to do a lot of stupid typing now , like:
    my_vec() : vector<int>() {}
    // etc.
    };

    Does anyone else find this behavior annoying? Instead, I would prefer
    for the compiler to implicitly declare all constructors that are not
    declared by the user.
  • John Harrison

    #2
    Re: implicit constructor declaration (user annoyed)


    "sb" <spam_bait101@y ahoo.com> wrote in message
    news:221dd125.0 402231407.1e1c0 b47@posting.goo gle.com...[color=blue]
    > If there is at least one user-defined constructor, no constructors are
    > implicitly declared.
    >
    > struct my_vec : public vector<int> {
    > double foo;
    > my_vec(size_t n) : vector<int>(2*n ) {}
    > // oops, no default ctor any more
    > // have to do a lot of stupid typing now , like:
    > my_vec() : vector<int>() {}
    > // etc.
    > };
    >
    > Does anyone else find this behavior annoying? Instead, I would prefer
    > for the compiler to implicitly declare all constructors that are not
    > declared by the user.[/color]

    Personally I would prefer no constructors to be implicitly defined. But I
    think the purpose behind the rules as they are is to define the minimum
    implicit constructors will remaining compatible with C.

    E.g. this code has to compile as C and C++.

    // C code
    typedef struct
    {
    int x;
    } X;

    X x; // use of implicit default constructor
    X y = x; // use of implicit copy constructor

    As soon as you define one constructor, you are no longer compatible with C
    anyway, so the rules can be tightened.

    john


    Comment

    • John Harrison

      #3
      Re: implicit constructor declaration (user annoyed)


      "John Harrison" <john_andronicu s@hotmail.com> wrote in message
      news:c1duao$1hs qre$1@ID-196037.news.uni-berlin.de...[color=blue]
      >
      > "sb" <spam_bait101@y ahoo.com> wrote in message
      > news:221dd125.0 402231407.1e1c0 b47@posting.goo gle.com...[color=green]
      > > If there is at least one user-defined constructor, no constructors are
      > > implicitly declared.
      > >
      > > struct my_vec : public vector<int> {
      > > double foo;
      > > my_vec(size_t n) : vector<int>(2*n ) {}
      > > // oops, no default ctor any more
      > > // have to do a lot of stupid typing now , like:
      > > my_vec() : vector<int>() {}[/color][/color]

      Actually you don't have to do that

      my_vec() {}

      is good enough, no too many keystrokes. Or even this

      my_vec(size_t n = 0) : vector<int>(2*n ) {}

      And don't publically inherit from STL container classes, its bad form.

      john


      Comment

      • Mike Wahler

        #4
        Re: implicit constructor declaration (user annoyed)


        "sb" <spam_bait101@y ahoo.com> wrote in message
        news:221dd125.0 402231407.1e1c0 b47@posting.goo gle.com...[color=blue]
        > If there is at least one user-defined constructor, no constructors are
        > implicitly declared.
        >
        > struct my_vec : public vector<int> {
        > double foo;
        > my_vec(size_t n) : vector<int>(2*n ) {}
        > // oops, no default ctor any more
        > // have to do a lot of stupid typing now , like:
        > my_vec() : vector<int>() {}
        > // etc.
        > };
        >
        > Does anyone else find this behavior annoying? Instead, I would prefer
        > for the compiler to implicitly declare all constructors that are not
        > declared by the user.[/color]

        struct my_vec : public vector<int> {
        double foo;

        public:
        my_vec(std::vec tor<int>::size_ type n = 0) // default ctor
        : vector<int>(2*n ) {} };
        };

        BTW why are you inheriting from std::vector?

        -Mike


        Comment

        • Andrey Tarasevich

          #5
          Re: implicit constructor declaration (user annoyed)

          sb wrote:[color=blue]
          > If there is at least one user-defined constructor, no constructors are
          > implicitly declared.
          > ...[/color]

          Not exactly true. Copy constructor is always implicitly declared (unless
          you explicitly declare copy constructor yourself). Explicit declaration
          of non-copy constructor will not suppress implicit declaration of copy
          constructor.

          --
          Best regards,
          Andrey Tarasevich

          Comment

          • E. Robert Tisdale

            #6
            Re: implicit constructor declaration (user annoyed)

            sb wrote:[color=blue]
            > If there is at least one user-defined constructor, no constructors are
            > implicitly declared.
            >
            > struct my_vec: public vector<int> {[/color]
            private:[color=blue]
            > double foo;[/color]
            public:
            my_vec(size_t n = 0): vector<int>(2*n ) { }[color=blue]
            > // etc.
            > };[/color]

            [color=blue]
            > Does anyone else find this behavior annoying?[/color]

            Not me.
            [color=blue]
            > Instead, I would prefer
            > for the compiler to implicitly declare all constructors
            > that are not declared by the user.[/color]


            Comment

            • Cy Edmunds

              #7
              Re: implicit constructor declaration (user annoyed)

              "sb" <spam_bait101@y ahoo.com> wrote in message
              news:221dd125.0 402231407.1e1c0 b47@posting.goo gle.com...[color=blue]
              > If there is at least one user-defined constructor, no constructors are
              > implicitly declared.
              >[/color]

              You certainly wrote an unconvincing example:
              [color=blue]
              > struct my_vec : public vector<int> {[/color]

              deriving from std::vector ? ugh
              [color=blue]
              > double foo;[/color]

              public data member. ugh again
              [color=blue]
              > my_vec(size_t n) : vector<int>(2*n ) {}[/color]

              this constructor converts integers to my_vec's because you neglected to
              declare it explicit
              [color=blue]
              > // oops, no default ctor any more
              > // have to do a lot of stupid typing now , like:[/color]

              I am tempted to say that you have already done a lot of stupid typing, but
              that wouldn't be a quality statement, so I won't. :)
              [color=blue]
              > my_vec() : vector<int>() {}[/color]

              my_vec() {} doesn't look so onerous
              [color=blue]
              > // etc.
              > };
              >
              > Does anyone else find this behavior annoying? Instead, I would prefer
              > for the compiler to implicitly declare all constructors that are not
              > declared by the user.[/color]

              Perhaps you are a bit too easily annoyed. This rule seems reasonable,
              doesn't stop anybody from doing what they want, and in any event is already
              established by many years of usage.

              --
              Cy



              Comment

              • sb

                #8
                Re: implicit constructor declaration (user annoyed)

                "John Harrison" <john_andronicu s@hotmail.com> wrote in message news:<c1dufk$1h 4gl7$1@ID-196037.news.uni-berlin.de>...[color=blue]
                > "John Harrison" <john_andronicu s@hotmail.com> wrote in message
                > news:c1duao$1hs qre$1@ID-196037.news.uni-berlin.de...[color=green]
                > >
                > > "sb" <spam_bait101@y ahoo.com> wrote in message
                > > news:221dd125.0 402231407.1e1c0 b47@posting.goo gle.com...[color=darkred]
                > > > If there is at least one user-defined constructor, no constructors are
                > > > implicitly declared.
                > > >
                > > > struct my_vec : public vector<int> {
                > > > double foo;
                > > > my_vec(size_t n) : vector<int>(2*n ) {}
                > > > // oops, no default ctor any more
                > > > // have to do a lot of stupid typing now , like:
                > > > my_vec() : vector<int>() {}[/color][/color]
                >
                > Actually you don't have to do that
                >
                > my_vec() {}
                >
                > is good enough, no too many keystrokes. Or even this
                >
                > my_vec(size_t n = 0) : vector<int>(2*n ) {}[/color]

                The snippet is merely an illustration. It could have been

                my_vec(size_t n) : vector<int>(2*n + 1) {}
                [color=blue]
                >
                > And don't publically inherit from STL container classes, its bad form.[/color]

                Arghh! If I had a dime for every time I heard this...

                Should I use containment and redefine all methods instead? (lots and
                lots of stupid wrapper code). And what if I want my_vec to *BE* a
                vector<int> ? No "style" or "possible misuse" considerations will make
                up for such braindamage.

                I'm sure some people feel very productive when they write

                private:
                t m_foo;
                public:
                const t& foo() const { return m_foo; }
                t& foo() { return m_foo; }

                and then go on to replicate most of the contents of std::vector.
                Wheeee! Accessors! Const-correct ones! Wheee! 300 lines of code in one
                hour. The manager must be realy proud of me! Thanks. I think I'll
                pass.

                Comment

                • John Harrison

                  #9
                  Re: implicit constructor declaration (user annoyed)

                  > > And don't publically inherit from STL container classes, its bad form.[color=blue]
                  >
                  > Arghh! If I had a dime for every time I heard this...
                  >
                  > Should I use containment and redefine all methods instead? (lots and
                  > lots of stupid wrapper code). And what if I want my_vec to *BE* a
                  > vector<int> ? No "style" or "possible misuse" considerations will make
                  > up for such braindamage.
                  >[/color]

                  The only case I heard where someone convincingly argued for deriving from a
                  standard container was a teacher who wanted a class exactly like std::string
                  but wanted to catch null pointer errors, for the benefit of his students who
                  were making that sort of error.

                  Almost every time I see derivation from a standard container it is because
                  someone wants to avoid the trouble of writing three of four wrapper methods
                  and doesn't know or doesn't care that they are needlessly inheriting scores
                  of methods from the parent class.

                  So I'll revise my advice, don't inherit from std::vector unless you have
                  good reason and you know what you are doing. I guess there is a small number
                  of cases where you want a class with *exactly* the same interface as
                  std::vector but with some additional behaviour, but I think its very rare.

                  john


                  Comment

                  • Andre Heinen

                    #10
                    Re: implicit constructor declaration (user annoyed)

                    On 23 Feb 2004 22:52:49 -0800, spam_bait101@ya hoo.com (sb) wrote:[color=blue]
                    >
                    >I'm sure some people feel very productive when they write
                    >
                    >private:
                    > t m_foo;
                    >public:
                    > const t& foo() const { return m_foo; }
                    > t& foo() { return m_foo; }
                    >
                    >and then go on to replicate most of the contents of std::vector.
                    >Wheeee! Accessors! Const-correct ones! Wheee! 300 lines of code in one
                    >hour. The manager must be realy proud of me! Thanks. I think I'll
                    >pass.[/color]

                    Actually those 300 lines of code can save you *lots* of time. If
                    m_foo is public, what will happen when you will have to change
                    your class's implementation? Imagine this:

                    class T_Wrapper {
                    // no const-correctness in this class because it isn't
                    // what we're talking about
                    public:
                    T foo;
                    void print() {
                    string s = makeStringRepre sentation();
                    cout << s;
                    }
                    string makeStringRepre sentation() {
                    // lots of time-consuming processing here
                    }
                    };

                    And in the client code:

                    void f(T_Wrapper& tw) {
                    tw.foo = someValue;
                    tw.print();
                    }

                    One day you decide to optimize makeStringRepre sentation():

                    class T_Wrapper {
                    public:
                    T foo;
                    string cachedStringRep ;
                    bool cacheIsUpToDate ;
                    void print() {
                    if ( ! cacheIsUpToDate ) {
                    cachedStringRep = makeStringRepre sentation();
                    cacheIsUpToDate = true;
                    }
                    cout << cachedStringRep ;
                    }
                    string makeStringRepre sentation() {
                    // same as above
                    }
                    void setFoo(T newFoo) {
                    foo = newFoo;
                    cacheIsUpToDate = false; // let's not forget this
                    }
                    };

                    Well, now f() is broken, because it changes foo without setting
                    cacheIsUpToDate to false. And so is all your client code. You
                    have to rewrite (or at least check) *everything*.

                    I think data members should be private even if they are part of
                    the interface. Unless, of course, you have some good reason to
                    do otherwise.

                    And, by the way, const-correctness is useful too...
                    ;-)

                    --
                    Andre Heinen
                    My address is "a dot heinen at europeanlink dot com"

                    Comment

                    Working...