Overloaded typecast operators and copy constructors

Discussion in 'C++' started by masood.iqbal@lycos.com, Feb 7, 2005.

  1. Guest

    I have a few questions regarding overloaded typecast
    operators and copy constructors that I would like an
    answer for. Thanks in advance.

    Masood



    (1) In some examples that I have seen pertaining to
    casting class A to class B, the implementation of the
    overloaded typecast operator does something like this:

    A::eek:perator B(...)
    {
    B localCopy(...);
    // perhaps some attributes of the "this" object
    // are passed to the constructor

    return localCopy;
    }

    Is this correct? Aren't we returning a local copy of
    B?


    (2) It appears that the following syntaxes are
    equivalent:
    [Here b is an instance of Class Y and Class Y has an
    overloaded typecast operator for Class X]
    (a) X c = (X)b; // Typecast style
    (b) X c = X(b); // Function call style

    Is this correct?


    (3) I am surprised that the typecasting to self type is
    allowed. If we have a class that supports both a copy
    constructor with one argument and an overloaded
    typecast operator to its own type (for whatever
    reason), it appears that they will have identical
    calling syntaxes.

    Is this correct? If this is correct, how does the
    compiler remove the ambiguity.

    I have a small coding sample that illustrates my
    doubts.


    /////////////////////////////////////////////////////////////
    #include <string.h>
    #include <iostream.h>

    class First
    {
    int value;
    public:
    First(int i = 0)
    {
    value = i;
    }

    operator int() // typecast to integer
    {
    return value;
    }
    };


    class Second
    {
    int data;
    char label[100];

    public:
    Second(int i = 0, char* str = "???")
    {
    data = i;
    strcpy(label, str);
    }

    Second(const Second& obj) // Copy constructor
    {
    cout << "Copy constructor called\n";
    data = obj.data;
    strcpy(label, obj.label);
    }

    operator char*() // typecast to char*
    {
    return label;
    }

    operator First() // typecast to First
    {
    First f(data);
    return f;
    }

    operator Second() // typecast to Self-type
    {
    cout << "Typecast operator to self called\n";
    Second s(data, label);
    return s;
    }
    };


    int
    main()
    {
    First first_a(56);

    cout << "It is " << (int)first_a << endl;

    Second second_b(98, "Howdy Doody");

    First first_c = (First)second_b; // typecast style conversion
    First first_d = First(second_b); // function call style conversion

    cout << "ONE: It is " << (int)first_c
    << " and " << (char *)second_b << endl;
    cout << "TWO: It is " << (int)first_d
    << " and " << (char *)second_b << endl;

    Second second_e(second_b);
    // What got called ---- the overloaded typecast
    // self-type or the copy constructor?

    return 0;
    }
     
    , Feb 7, 2005
    #1
    1. Advertising

  2. <> wrote...
    >I have a few questions regarding overloaded typecast
    > operators and copy constructors that I would like an
    > answer for. Thanks in advance.
    >
    > Masood
    >
    >
    >
    > (1) In some examples that I have seen pertaining to
    > casting class A to class B, the implementation of the
    > overloaded typecast operator does something like this:
    >
    > A::eek:perator B(...)
    > {
    > B localCopy(...);
    > // perhaps some attributes of the "this" object
    > // are passed to the constructor
    >
    > return localCopy;
    > }
    >
    > Is this correct? Aren't we returning a local copy of
    > B?


    It is correct. We're returning a copy of 'localCopy'.

    > (2) It appears that the following syntaxes are
    > equivalent:
    > [Here b is an instance of Class Y and Class Y has an
    > overloaded typecast operator for Class X]
    > (a) X c = (X)b; // Typecast style
    > (b) X c = X(b); // Function call style
    >
    > Is this correct?


    Depends on what 'X' is like. If it has a constructor that
    accepts 'Y', then no, it's not correct.

    > (3) I am surprised that the typecasting to self type is
    > allowed.


    You mean

    struct A {
    operator A();
    };

    ?

    > If we have a class that supports both a copy
    > constructor with one argument and an overloaded
    > typecast operator to its own type (for whatever
    > reason), it appears that they will have identical
    > calling syntaxes.


    It does, doesn't it?

    > Is this correct? If this is correct, how does the
    > compiler remove the ambiguity.


    The conversion to the same object type is never used
    directly. It can only be reached through a virtual
    function call. See 12.3.2/1.

    >
    > I have a small coding sample that illustrates my
    > doubts.
    >
    >
    > /////////////////////////////////////////////////////////////
    > #include <string.h>
    > #include <iostream.h>


    #include <iostream>
    using std::cout;
    using std::endl;

    >
    > class First
    > {
    > int value;
    > public:
    > First(int i = 0)
    > {
    > value = i;
    > }
    >
    > operator int() // typecast to integer
    > {
    > return value;
    > }
    > };
    >
    >
    > class Second
    > {
    > int data;
    > char label[100];
    >
    > public:
    > Second(int i = 0, char* str = "???")


    Second(int i = 0, char const* str = "???")

    > {
    > data = i;
    > strcpy(label, str);


    strncpy(label, str, 99);
    label[99] = 0;

    > }
    >
    > Second(const Second& obj) // Copy constructor
    > {
    > cout << "Copy constructor called\n";
    > data = obj.data;
    > strcpy(label, obj.label);
    > }
    >
    > operator char*() // typecast to char*
    > {
    > return label;
    > }
    >
    > operator First() // typecast to First
    > {
    > First f(data);
    > return f;
    > }
    >
    > operator Second() // typecast to Self-type
    > {
    > cout << "Typecast operator to self called\n";
    > Second s(data, label);
    > return s;
    > }
    > };
    >
    >
    > int
    > main()
    > {
    > First first_a(56);
    >
    > cout << "It is " << (int)first_a << endl;
    >
    > Second second_b(98, "Howdy Doody");
    >
    > First first_c = (First)second_b; // typecast style conversion
    > First first_d = First(second_b); // function call style conversion
    >
    > cout << "ONE: It is " << (int)first_c
    > << " and " << (char *)second_b << endl;
    > cout << "TWO: It is " << (int)first_d
    > << " and " << (char *)second_b << endl;
    >
    > Second second_e(second_b);
    > // What got called ---- the overloaded typecast
    > // self-type or the copy constructor?


    The copy constructor.

    >
    > return 0;
    > }
    >
     
    Victor Bazarov, Feb 7, 2005
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. George Economos
    Replies:
    4
    Views:
    360
    Victor Bazarov
    Aug 23, 2005
  2. Jeremy Smith
    Replies:
    2
    Views:
    602
    Jeremy Smith
    Aug 3, 2006
  3. iluvatar
    Replies:
    3
    Views:
    336
    Sylvester Hesp
    Feb 12, 2007
  4. Jess
    Replies:
    5
    Views:
    615
    Ron Natalie
    Jun 7, 2007
  5. srp113
    Replies:
    3
    Views:
    482
Loading...

Share This Page