2012-04-09 41 views
6

Ví dụ:Tại sao toán tử gán của lớp cha mẹ không thể truy cập từ lớp được thừa kế đối tượng

class C 
{ 
    public: 
    void operator =(int i) {} 
}; 

class SubC : public C 
{ 
}; 

Sau đây cho lỗi biên dịch:

SubC subC; 
subC = 0; 

"không phù hợp cho 'operator =' trong 'subC = 0 '"

Một số nguồn cho biết đó là do các toán tử gán không được kế thừa. Nhưng không phải đơn giản chỉ vì bản sao chép được gán mặc định của SubC sẽ làm lu mờ chúng?

Trả lời

11

Toán tử gán bản sao được tạo tự động trong lớp dẫn xuất. Điều này làm cho toán tử gán của lớp cơ sở bị ẩn do các quy tắc ẩn tên thường lệ của C++. Bạn có thể bỏ ẩn tên trong lớp cơ sở thông qua chỉ thị "đang sử dụng". Ví dụ:

class C 
{ 
    public: 
    void operator =(int i) {} 
}; 

class SubC : public C 
{ 
    public: 
    using C::operator=; 
}; 
+1

Hoặc gọi nó trực tiếp 'subC.C :: operator = (0);' –

2

Toán tử gán bản sao cho lớp cơ sở không có chữ ký bắt buộc cho toán tử gán bản sao cho lớp dẫn xuất. Nó được thừa hưởng bởi lớp dẫn xuất, nhưng không cấu thành một toán tử gán bản sao trong nó. Vì vậy, mặc dù các toán tử gán được thừa hưởng, giống như các hàm thành viên khác, nó không cung cấp việc gán bản sao.

+4

Điều đó không đúng. Ví dụ, toán tử + có thể được kế thừa. –

1

Tôi đã không làm điều đó, nhưng theo The Man Himself (Stroustrup) đó là một tính năng của C++ 11 để làm điều đó với nhà thầu, nhưng nó được trong từ C++ 98 để làm điều đó với các phương pháp khác.

này được dỡ bỏ TRỰC TIẾP từ liên kết:

People sometimes are confused about the fact that ordinary scope rules apply to class members. In particular, a member of a base class is not in the same scope as a member of a derived class:

struct B { 
    void f(double); 
}; 

struct D : B { 
    void f(int); 
}; 

B b; b.f(4.5); // fine 
D d; d.f(4.5); // surprise: calls f(int) with argument 4 

In C++98, we can "lift" a set of overloaded functions from a base class into a derived class:

struct B { 
    void f(double); 
}; 

struct D : B { 
    using B::f;  // bring all f()s from B into scope 
    void f(int); // add a new f() 
}; 

B b; b.f(4.5); // fine 
D d; d.f(4.5); // fine: calls D::f(double) which is B::f(double) 

Vì vậy, có ya đi. Bạn có thể có thể "lấy nó nếu bạn muốn nó" ngay cả trước khi C++ 11, mặc dù tôi đã không thử nó bản thân mình.

0

Trừ toán tử gán bản sao, toán tử quá tải khác có thể được kế thừa.

Tôi đồng ý với ý kiến ​​rằng mặc định được xây dựng sao chép giao SubC làm lu mờ toán tử gán quá tải của C.

Nếu SubC không cung cấp một nhà điều hành sao chép bài tập, biên dịch sẽ synthese một hoạt động sao chép chuyển nhượng, như theo:

class SubC : public C 
{ 
public: 
    SubC & operator=(const SubC & other); 
} 

thì 'SubC & operator = (const SubC & khác)' làm lu mờ hành phân công của C, kết quả do lỗi biên dịch.

Nếu

SubC other; 
SubC subC; 

subC = other; 

sau đó, trường hợp này, biên dịch ok.

Các vấn đề liên quan