Overloaded typecast operators and copy constructors

M

masood.iqbal

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;
}
 
V

Victor Bazarov

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,905
Latest member
Kristy_Poole

Latest Threads

Top