Wrong Constructor Called

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

    Wrong Constructor Called

    I have a situation where the wrong constructor is being called. I
    have defined 2 constructors with different parameter types that are
    defined as follows...

    class __declspec(dlle xport)CColumn : public CColumnBase
    {
    public:

    CColumn(CString columnType,CObj ect *aOwner, CString anId);
    CColumn(CString columnType,CObj ect *aOwner, bool batchUpdated);
    ....
    }

    The implementation of these functions looks like this...

    CColumn::CColum n(CString columnType, CObject *aOwner, CString anId)
    {
    setColumnType(c olumnType);
    setOwner(aOwner );
    setId(anId);
    setLength(10);
    setPrecision(5) ;
    setField();
    setBatchUpdated (false);
    }

    CColumn::CColum n(CString columnType, CObject *aOwner, bool
    batchUpdated)
    {
    setColumnType(c olumnType);
    setOwner(aOwner );
    setId("");
    setLength(10);
    setPrecision(5) ;
    setField();
    setBatchUpdated (batchUpdated);
    }

    When the line below in the CDual() constructor gets called, the
    constructor with the signature of CColumn::CColum n(CString columnType,
    CObject *aOwner, bool batchUpdated) gets invoked, rather than the one
    I want.


    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////
    IMPLEMENT_DYNCR EATE( CDual, CDomain )

    CDual::CDual()
    {
    ...
    addColumn(new CColumn(TIMESTA MP_COLUMN,this, "TIMESTAMP" ));
    ...
    }

    Does anyone have any idea why this is happening and how to avoid this
    issue?

    Thanks,

    Joe
  • Ron Natalie

    #2
    Re: Wrong Constructor Called


    "Joe" <jribble@purina .com> wrote in message news:ec8eef68.0 401210627.2c31a 760@posting.goo gle.com...[color=blue]
    > When the line below in the CDual() constructor gets called, the
    > constructor with the signature of CColumn::CColum n(CString columnType,
    > CObject *aOwner, bool batchUpdated) gets invoked, rather than the one
    > I want.
    >[/color]

    Because the bool is a better match for char* than CString is. Any pointer
    can be converted to bool, and that is a standard conversion sequence.
    I assume CString has a converting constructor that takes a char*. This
    is a user-defined conversion sequence. The standard conversion sequence
    wins out.

    You'll either have to make your overloads less ambiguous, or explicitly do
    something to the call to make it not match bool (like converting it to CString yourself).
    new CColumn(TIMESTA MP_COLUMN, this, CString("TIMEST AMP"));

    Comment

    • Karl Heinz Buchegger

      #3
      Re: Wrong Constructor Called

      Joe wrote:[color=blue]
      >
      >
      > CDual::CDual()
      > {
      > ...
      > addColumn(new CColumn(TIMESTA MP_COLUMN,this, "TIMESTAMP" ));
      > ...
      > }
      >
      > Does anyone have any idea why this is happening[/color]

      I am not sure if this is a compiler bug or not.
      But obviously the compiler prevers the conversion
      from a character pointer to a bool over the construction
      of a temporary object.
      [color=blue]
      > and how to avoid this
      > issue?[/color]

      Simple. Force the compiler to do it:

      {
      ...
      addColumn(new CColumn(TIMESTA MP_COLUMN,this, CString( "TIMESTAMP" )));
      ...
      }

      another workaround would be to introduce a third constructor which
      takes a const char*


      --
      Karl Heinz Buchegger
      kbuchegg@gascad .at

      Comment

      • jeffc

        #4
        Re: Wrong Constructor Called


        "Ron Natalie" <ron@sensor.com > wrote in message
        news:400e9258$0 $148$9a6e19ea@n ews.newshosting .com...[color=blue]
        >
        > "Joe" <jribble@purina .com> wrote in message[/color]
        news:ec8eef68.0 401210627.2c31a 760@posting.goo gle.com...[color=blue][color=green]
        > > When the line below in the CDual() constructor gets called, the
        > > constructor with the signature of CColumn::CColum n(CString columnType,
        > > CObject *aOwner, bool batchUpdated) gets invoked, rather than the one
        > > I want.
        > >[/color]
        >
        > Because the bool is a better match for char* than CString is. Any[/color]
        pointer[color=blue]
        > can be converted to bool, and that is a standard conversion sequence.
        > I assume CString has a converting constructor that takes a char*. This
        > is a user-defined conversion sequence. The standard conversion sequence
        > wins out.[/color]

        Is this true for the language as part of the standard, or is it compiler
        dependent and you're inferring that's his implementation?


        Comment

        • Kevin Saff

          #5
          Re: Wrong Constructor Called

          "Joe" <jribble@purina .com> wrote in message
          news:ec8eef68.0 401210627.2c31a 760@posting.goo gle.com...[color=blue]
          > I have a situation where the wrong constructor is being called. I
          > have defined 2 constructors with different parameter types that are
          > defined as follows...
          >
          > class __declspec(dlle xport)CColumn : public CColumnBase
          > {
          > public:
          >
          > CColumn(CString columnType,CObj ect *aOwner, CString anId);
          > CColumn(CString columnType,CObj ect *aOwner, bool batchUpdated);
          > ...
          > }
          >[/color]
          [SNIP implementation details][color=blue]
          >
          > CDual::CDual()
          > {
          > ...
          > addColumn(new CColumn(TIMESTA MP_COLUMN,this, "TIMESTAMP" ));
          > ...
          > }
          >
          > Does anyone have any idea why this is happening and how to avoid this
          > issue?
          >
          > Thanks,
          >
          > Joe[/color]
          It's because you aren't calling the constructor with a (CString) - you are
          calling it with "TIMESTAMP" which is a (char const*). There is a
          language-defined conversion from a pointer to a bool (non-NULL -> true,
          NULL -> false), which beats out the user-defined conversion from (char
          const*) to (CString). I don't remember the exact language rule here, but
          it's come up in my code before. You have several options:

          1) Instead call CColumn (TIMESTAMP_COLU MN, this, CString ("TIMESTAMP" ));
          2) Create a new constructor CColumn (CString columnType,CObj ect *aOwner,
          char const *anId);
          3) Change the argument orders, or add an argument to a constructor.
          4) Use the named constructor idiom. (static CColumn *createById (...);
          static CColumn *createBatch (...).
          5) Passing a bool to a constructor is often a hint to break the class into
          two, using polymorphism.

          What you do depends on several factors, including what code is yours. I
          don't recall if CColumn is an MFC class or not.

          HTH
          --
          KCS




          Comment

          • Ron Natalie

            #6
            Re: Wrong Constructor Called


            "Karl Heinz Buchegger" <kbuchegg@gasca d.at> wrote in message news:400E9676.5 71EDED2@gascad. at...[color=blue]
            > I am not sure if this is a compiler bug or not.
            > But obviously the compiler prevers the conversion
            > from a character pointer to a bool over the construction
            > of a temporary object.[/color]

            It's not a bug. The conversion of a pointer to bool is a standard
            conversion sequence. The conversion to CString is a user-defined
            conversion. A standard conversion sequence is preferred over a
            user-defined conversion. That's the language.

            Comment

            • Ron Natalie

              #7
              Re: Wrong Constructor Called


              "jeffc" <nobody@nowhere .com> wrote in message news:400e9d3a_4 @news1.prserv.n et...[color=blue]
              > Is this true for the language as part of the standard, or is it compiler
              > dependent and you're inferring that's his implementation?
              >[/color]
              It's the way the C++ language works. There's nothing wrong
              with his compiler in this regard.

              Comment

              • Karl Heinz Buchegger

                #8
                Re: Wrong Constructor Called

                Ron Natalie wrote:[color=blue]
                >
                > "Karl Heinz Buchegger" <kbuchegg@gasca d.at> wrote in message news:400E9676.5 71EDED2@gascad. at...[color=green]
                > > I am not sure if this is a compiler bug or not.
                > > But obviously the compiler prevers the conversion
                > > from a character pointer to a bool over the construction
                > > of a temporary object.[/color]
                >
                > It's not a bug. The conversion of a pointer to bool is a standard
                > conversion sequence. The conversion to CString is a user-defined
                > conversion. A standard conversion sequence is preferred over a
                > user-defined conversion. That's the language.[/color]


                Thank's for clearification.

                --
                Karl Heinz Buchegger
                kbuchegg@gascad .at

                Comment

                • Chris Theis

                  #9
                  Re: Wrong Constructor Called


                  "Joe" <jribble@purina .com> wrote in message
                  news:ec8eef68.0 401210627.2c31a 760@posting.goo gle.com...[color=blue]
                  > I have a situation where the wrong constructor is being called. I
                  > have defined 2 constructors with different parameter types that are
                  > defined as follows...
                  >[/color]
                  [SNIP][color=blue]
                  > Does anyone have any idea why this is happening and how to avoid this
                  > issue?[/color]

                  This is a problem of the conversion sequence. The standard states that the
                  order of conversions are 1. standard-conversion, 2. user defined
                  conversions, 3. elipsis conversions. The conversion to bool is a valid
                  standard conversion for any pointer as it is indicated in section 4.12 of
                  the standard. CString has a ctor enable implicit user conversions for string
                  literals. However, the standard conversion to bool wins due to the ordering.
                  What you have to do is to disamiguate the ctor call by supplying a CString
                  object as the 3rd parameter or provide another ctor which can take a const
                  char*.

                  Regards
                  Chris


                  Comment

                  • Chris Theis

                    #10
                    Re: Wrong Constructor Called


                    "jeffc" <nobody@nowhere .com> wrote in message
                    news:400e9d3a_4 @news1.prserv.n et...[color=blue]
                    >
                    > "Ron Natalie" <ron@sensor.com > wrote in message
                    > news:400e9258$0 $148$9a6e19ea@n ews.newshosting .com...[color=green]
                    > >
                    > > "Joe" <jribble@purina .com> wrote in message[/color]
                    > news:ec8eef68.0 401210627.2c31a 760@posting.goo gle.com...[color=green][color=darkred]
                    > > > When the line below in the CDual() constructor gets called, the
                    > > > constructor with the signature of CColumn::CColum n(CString columnType,
                    > > > CObject *aOwner, bool batchUpdated) gets invoked, rather than the one
                    > > > I want.
                    > > >[/color]
                    > >
                    > > Because the bool is a better match for char* than CString is. Any[/color]
                    > pointer[color=green]
                    > > can be converted to bool, and that is a standard conversion sequence.
                    > > I assume CString has a converting constructor that takes a char*. This
                    > > is a user-defined conversion sequence. The standard conversion[/color][/color]
                    sequence[color=blue][color=green]
                    > > wins out.[/color]
                    >
                    > Is this true for the language as part of the standard, or is it compiler
                    > dependent and you're inferring that's his implementation?
                    >[/color]

                    It's defined by the standard in section 13.3.3.1 (ISO:IEC 14882:1998(E))

                    Chris


                    Comment

                    • jeffc

                      #11
                      Re: Wrong Constructor Called


                      "Ron Natalie" <ron@sensor.com > wrote in message
                      news:400e9f1a$0 $134$9a6e19ea@n ews.newshosting .com...[color=blue]
                      >
                      > "jeffc" <nobody@nowhere .com> wrote in message[/color]
                      news:400e9d3a_4 @news1.prserv.n et...[color=blue][color=green]
                      > > Is this true for the language as part of the standard, or is it compiler
                      > > dependent and you're inferring that's his implementation?
                      > >[/color]
                      > It's the way the C++ language works. There's nothing wrong
                      > with his compiler in this regard.[/color]

                      Whaddya know. Personally I don't think that conversion should be there - it
                      seems meaningless for a literal string.


                      Comment

                      • Ron Natalie

                        #12
                        Re: Wrong Constructor Called


                        "jeffc" <nobody@nowhere .com> wrote in message news:400ee600_3 @news1.prserv.n et...[color=blue]
                        >[/color]
                        [color=blue]
                        >
                        > Whaddya know. Personally I don't think that conversion should be there - it
                        > seems meaningless for a literal string.
                        >[/color]
                        What conversion are you talking about? First off, it's pure conjecture what CString
                        does because it's not a standard type. I'm just assuming it has a constructor of the
                        form CString(const char*). Second, string literals don't make a string. They make
                        a character array. It's braindamage carried over from C. char* sucks as a string
                        type.

                        Comment

                        • Howard

                          #13
                          Re: Wrong Constructor Called


                          "jeffc" <nobody@nowhere .com> wrote in message
                          news:400ee600_3 @news1.prserv.n et...[color=blue]
                          >
                          > "Ron Natalie" <ron@sensor.com > wrote in message
                          > news:400e9f1a$0 $134$9a6e19ea@n ews.newshosting .com...[color=green]
                          > >
                          > > "jeffc" <nobody@nowhere .com> wrote in message[/color]
                          > news:400e9d3a_4 @news1.prserv.n et...[color=green][color=darkred]
                          > > > Is this true for the language as part of the standard, or is it[/color][/color][/color]
                          compiler[color=blue][color=green][color=darkred]
                          > > > dependent and you're inferring that's his implementation?
                          > > >[/color]
                          > > It's the way the C++ language works. There's nothing wrong
                          > > with his compiler in this regard.[/color]
                          >
                          > Whaddya know. Personally I don't think that conversion should be there -[/color]
                          it[color=blue]
                          > seems meaningless for a literal string.
                          >
                          >[/color]
                          It's because a string literal is treated as a const char array, and a
                          pointer to that array is created and used. The conversion is then really
                          from a char* to a bool, which makes a great deal of sense, since it is
                          common to check for a non-null pointer by writing something like

                          if (pointer_to_som ething){......}


                          -Howard



                          Comment

                          • Ron Natalie

                            #14
                            Re: Wrong Constructor Called


                            "Howard" <alicebt@hotmai l.com> wrote in message news:bumtn9$mb1 @dispatch.conce ntric.net...[color=blue]
                            > It's because a string literal is treated as a const char array,[/color]
                            That's because it IS a const char array.

                            Comment

                            • jeffc

                              #15
                              Re: Wrong Constructor Called


                              "Ron Natalie" <ron@sensor.com > wrote in message
                              news:400ee6df$0 $221$9a6e19ea@n ews.newshosting .com...[color=blue]
                              >
                              > "jeffc" <nobody@nowhere .com> wrote in message[/color]
                              news:400ee600_3 @news1.prserv.n et...[color=blue][color=green]
                              > >[/color]
                              >[color=green]
                              > >
                              > > Whaddya know. Personally I don't think that conversion should be[/color][/color]
                              there - it[color=blue][color=green]
                              > > seems meaningless for a literal string.
                              > >[/color]
                              > What conversion are you talking about? First off, it's pure conjecture[/color]
                              what CString[color=blue]
                              > does because it's not a standard type. I'm just assuming it has a[/color]
                              constructor of the[color=blue]
                              > form CString(const char*). Second, string literals don't make a[/color]
                              string. They make[color=blue]
                              > a character array. It's braindamage carried over from C. char* sucks[/color]
                              as a string[color=blue]
                              > type.[/color]

                              You're quite correct, but I was talking about a string literal to bool.
                              It's a silly conversion, virtually certain to be a mistake.


                              Comment

                              Working...