30/09/2018, 23:46

Chuyển kiểu của đối tượng, nạp chồng toán tử <tên class> trong c++

mình có đọc 1 cuốn về c++, hình như được dịch từ sách nước ngoài,vì mình thấy câu văn k được thoát nghĩa cho lắm, kiểu sử dụng từ điển để dịch, chứ k dịch ngữ cảnh văn phạm
có đoạn sau
nội dung nói về chuyển kiểu đối tượng (tương minh hoặc không tương minh)
và nạp chồng toán tử <tên kiểu> mình thấy cái này có gì đó sai sai, toán tử sao lại là class.

Cái gì xảy ra nếu chúng ta muốn thực hiện chuyển kiểu ngược lại từ kiểu
lớp thành một kiểu khác? Trong trường hợp này các hàm xây dựng không thể
được sử dụng bởi vì chúng luôn trả về một đối tượng của lớp mà chúng thuộc
về. Để thay thế, một lớp có thể định nghĩa một hàm thành viên mà chuyển rõ
ràng một đối tượng thành một kiểu mong muốn.
Ví dụ, với lớp Rectangle đã cho chúng ta có thể định nghĩa một hàm
chuyển kiểu thực hiện chuyển một hình chữ nhật thành một điểm bằng cách
tái định nghĩa toán tử kiểu Point trong lớp Rectangle:
classRectangle {
public:
Rectangle (intleft,int top,intright,intbottom);
Rectangle (Point &p, Point &q);
//...
operatorPoint () {returnbotRight -topLeft;}
private:
PointtopLeft;
PointbotRight;
};
Toán tử này được định nghĩa để chuyển một hình chữ nhật thành một điểm
mà tọa độ của nó tiêu biểu cho độ rộng và chiều cao của hình chữ nhật. Vì
thế, trong đoạn mã
Point p(5,5);
Rectangle r(10,10,20,30);
r +p;
trước hết hình chữ nhật r được chuyển không tường minh thành một đối tượng
Point bởi toán tử chuyển kiểu và sau đó được cộng vào p.
Chuyển kiểu Point cũng có thể được áp dụng tường minh bằng cách sử
dụng ký hiệu ép kiểu thông thường. Ví dụ:
Point(r); //épkiểu tườngminh thành Point
(Point)r; //épkiểu tườngminh thành Point
Thông thường với kiểu người dùng định nghĩa X đã cho và kiểu Y khác
(có sẵn hay người dùng định nghĩa) thì:
• Hàm xây dựng được định nghĩa cho X nhận một đối số đơn kiểu Y sẽ
chuyển không tường minh các đối tượng Y thành các đối tượng X khi
được cần.
• Tái định nghĩa toán tử Y trong X sẽ chuyển không tường minh các đối
tượng X thành các đối tượng Y khi được cần.
classX{
//...
X(Y&); //chuyển Y thànhX
operator Y (); // chuyển X thànhY
};
Một trong những bất lợi của các phương thức chuyển kiểu do người dùng
định nghĩa là nếu chúng không được sử dụng một cách hạn chế thì chúng có
thể làm cho các hoạt động của chương trình là khó có thể tiên đoán. Cũng có
sự rủi ro thêm vào của việc tạo ra sự mơ hồ. Sự mơ hồ xảy ra khi trình biên
dịch có hơn một chọn lựa cho nó để áp dụng các qui luật chuyển kiểu người
dùng định nghĩa và vì thế không thể chọn được. Tất cả những trường hợp như
thế được báo cáo như những lỗi bởi trình biên dịch.
Để minh họa cho các mơ hồ có thể xảy ra, giả sử rằng chúng ta cũng định
nghĩa một hàm chuyển kiểu cho lớp Rectangle (nhận một đối số Point) cũng
như là tái định nghĩa các toán tử + và -:
classRectangle {
public:
Rectangle (intleft,int top,intright,intbottom);
Rectangle (Point &p, Point &q);
Rectangle(Point&p);
operatorPoint (){return botRight-topLeft;}
friend Rectangleoperator +(Rectangle &r,Rectangle &t);
friend Rectangleoperator - (Rectangle&r, Rectangle &t);
private:
PointtopLeft;
PointbotRight;
};
Bây giờ, trong
Point p(5,5);
Rectangle r(10,10,20,30);
r +p;
r + p có thể được thông dịch theo hai cách. Hoặc là
r + Rectangle(p) // choramộtRectangle
hoặc là:
Point(r)+p //choramột Point
Nếu lập trình viên không giải quyết sự mơ hồ bởi việc chuyển kiểu tường
minh thì trình biên dịch sẽ từ chối.
viết 01:47 ngày 01/10/2018

welcome to C++, (hầu như) cái gì cũng có thể nạp chồng được

operator MyClass::Type()const
{
    Type x;
    ...
    return x;
}

là hoàn toàn hợp lệ. Phương thức nạp chồng này để ép kiểu MyClass thành Type. Có thể gọi nó là “nạp chồng ép kiểu”.

MyClass a;
Type x = a;       //implicit cast - ép kiểu ngầm định
Type y = (Type)a; //explicit cast - ép kiểu tường minh kiểu C
Type y = static_cast<Type>(a);    //ép kiểu tường minh kiểu C++

Vì ép kiểu ngầm định thường dễ gây hiểu lầm (cho người đọc code lẫn trình biên dịch khi biên dịch), nên có thể buộc ép kiểu tường minh bằng cách thêm chữ explicit khi khai báo tên phương thức nạp chồng trong class:

explicit opeartor Type()const;

thì sẽ ko cho ép kiểu ngầm định nữa, hay viết Type x = a; sẽ tạo lỗi khi biên dịch.

abcxyz viết 01:52 ngày 01/10/2018

cái này là nạp chồng () , chứ trong sách , chỉ có mỗi tên class

viết 01:46 ngày 01/10/2018

nạp chồng () khác. Cái này nạp chồng ép kiểu: Type operator()() khác với operator Type()

vd

int operator()()const;                           //để có thể gọi (*this)()
double operator()(const std::string&, int)const; //để có thể gọi (*this)(str, n)

operator int()const;         //để có thể gọi static_cast<int>(*this);
operator double()const;      //để có thể gọi static_cast<double>(*this);
operator std::string()const; //để có thể gọi static_cast<std::string>(*this);

đúng là dễ lú lắm

abcxyz viết 02:00 ngày 01/10/2018

mình thấy với toán tử đơn hạng
nếu overloading bằng function member thì không có đối số vào
nếu overloading bằng friend fuciton hoặc bằng non-member function (dùng setter - getter ) thì có 1 đối

với toán tử nhị hạng
nếu overloading bằng function member thì có 1 đối
nếu overloading bằng friend fuciton hoặc bằng non-member function (dùng setter - getter ) thì có 2 đối

thường là đơn hạng hoặc nhị hạng
thế giờ mình muốn nạp chồng tam hạng
thì có được k nhỉ

ví dụ như biểu thức này

(a>b) ? a : b

abcxyz viết 01:51 ngày 01/10/2018

explicit opeartor Type()const;

explicit là gì vậy bạn, cái này mới quá, mình mới học c++

abcxyz viết 02:02 ngày 01/10/2018

operator MyClass::Type()const
{
Type x;

return x;
}

k có kiểu trả về, sao lại return x có kiểu type ?

abcxyz viết 01:49 ngày 01/10/2018

à mình hiểu hết rồi, chỉ còn mỗi 1 cái là
nạp chồng ép kiểu đó, k có kiểu trả về sao lại return được?

Bài liên quan
0