2009-02-19 33 views
9

Tôi có một lớp cơ sở triển khai toán tử ==. Tôi muốn viết một lớp khác, kế thừa lớp cơ sở và nên triển khai lại toán tử ==.thực hiện toán tử == khi sử dụng thừa kế

Dưới đây là một số mẫu mã:

#include <iostream> 
#include <string> 

class Person 
{ 
public: 
    Person(std::string Name) { m_Name = Name; }; 

    bool operator==(const Person& rPerson) 
    { 
    return m_Name == rPerson.m_Name; 
    } 

private: 
    std::string m_Name; 
}; 

class Employee : public Person 
{ 
public: 
    Employee(std::string Name, int Id) : Person(Name) { m_Id = Id; }; 

    bool operator==(const Employee& rEmployee) 
    { 

    return (Person::operator==(rEmployee)) && (m_Id == rEmployee.m_Id); 
    } 

private: 
    int m_Id; 
}; 

void main() 
{ 
    Employee* pEmployee1 = new Employee("Foo" , 1); 
    Employee* pEmployee2 = new Employee("Foo" , 2); 

    if (*pEmployee1 == *pEmployee2) 
    { 
    std::cout << "same employee\n"; 
    } 
    else 
    { 
    std::cout << "different employee\n"; 
    } 

    Person* pPerson1 = pEmployee1; 
    Person* pPerson2 = pEmployee2; 

    if (*pPerson1 == *pPerson2) 
    { 
    std::cout << "same person\n"; 
    } 
    else 
    { 
    std::cout << "different person\n"; 
    } 
} 

này mẫu mã cung cấp cho các kết quả sau:

different employee 
same person 

Nơi tôi muốn, ngay cả khi xử lý Person * con trỏ, để đảm bảo rằng họ là khác nhau .

Tôi phải giải quyết vấn đề này như thế nào?

Cảm ơn!

+0

tôi tin rằng bạn đang cố gắng giải quyết vấn đề sai. nếu bạn cần một toán tử == hoạt động dựa trên kiểu tham chiếu/kiểu con trỏ, bạn không nên sử dụng thừa kế ở vị trí đầu tiên. – hawk

Trả lời

8

Những gì bạn muốn làm là essentiall "ảo hóa" toán tử so sánh.

Vì các toán tử không thể ảo, bạn sẽ cần ủy quyền nó cho một thứ khác. Đây là một giải pháp khả thi.

class Person 
{ 
    public: 
     /* ... */ 
     bool operator==(const Person& rhs) 
     { 
     return m_Name == rPerson.m_Name && this->doCompare(rhs); 
     } 
    private: 
     virtual bool doCompare() = 0; 
    }; 
} 
class Employee : public Person 
{ 
    /* ... */ 
    private: 
     virtual bool doCompare(const Person& rhs) 
     { 
     bool bRetval = false; 
     const Employee* pRHSEmployee = dynamic_cast<const Employee*>(&rhs); 
     if (pEmployee) 
     { 
      bRetval = m_Id == pRHSEmployee->m_Id 
     } 
     return bRetval; 
     } 
}; 

Câu hỏi không rõ liệu Người có cần phải là lớp cụ thể hay không. Nếu vậy, bạn có thể làm cho nó không thuần ảo, và thực hiện nó để trả về true.

Điều này cũng sử dụng RTTI, mà bạn có thể hoặc có thể không hài lòng.

+0

C++ cho phép các nhà khai thác trở thành ảo. nhưng tôi sẽ không biến chúng thành ảo. tính đa hình và các toán tử thực sự không phù hợp với nhau rất tốt (và các hàm toán tử miễn phí rõ ràng không thể ảo được). –

+4

Nếu bạn định làm điều này, thì bạn nên gọi cả hai 'this-> doCompare (đó)' và 'that.doCompare (* this)' để đảm bảo tính đối xứng –

0

Bạn cần đặt Person :: operator == virtual.

+0

-1. Làm cho Person :: toán tử == virtual là không đủ: Employee :: operator == phải được viết lại để có cùng chữ ký. Hơn nữa, điều này vẫn dẫn đến vấn đề được chỉ ra bởi Douglas, tức là tính toán của hoạt động so sánh, đó là ... lạ. –

+0

Tôi không nghĩ rằng bạn có thể làm cho các nhà khai thác ảo. – JohnMcG

7

Thêm một hàm int ảo So sánh (const Person & rPerson) và sử dụng trong các nhà khai thác của bạn

5

Không có giải pháp gọn gàng cho vấn đề này.

Thực tế không có vấn đề gì, trong C++. Ý nghĩa của việc so sánh các thực thể trên cơ sở bình đẳng là gì?

EDIT: một số liên kết đến thiền liên quan đến việc thích hợp của bình đẳng áp dụng cho các đơn vị:

+0

Tôi không hiểu điểm của bạn. Bạn có thể giải thích chi tiết hơn, tại sao sự so sánh đó không có ý nghĩa? – jpfollenius

+0

Quan điểm của tôi là bình đẳng không có ý nghĩa về thực thể, và OP đang lãng phí thời gian của mình để giải quyết một cái gì đó không được giải quyết, cũng không thể giải quyết được (xem các cuộc tranh luận Java về triển khai isEquals) –

+0

... rất giống nhau, theo một nghĩa nào đó chúng ta có thể thấy chúng như bằng. Nhưng ai quan tâm chứ ? Mọi người đều giống nhau, hay không ... –

5

Bạn vẫn gặp vấn đề lớn nếu bạn có một người và một nhân viên - người đó có thể so sánh với nhân viên, chứ không phải nhân viên cho người đó. tức là:

(employee == person) != (person == employee) 

Đây là điều xấu (tm). Về cơ bản bạn đã thực hiện một nhà điều hành bình đẳng đó không phải là symmetric

Edit:

Ok, không có nhà khai thác ảo - thêm ảo Hãy so sánh chức năng đề nghị những nơi khác tôi nghĩ - nhưng bạn vẫn có vấn đề đối xứng.

0

Bạn cũng có thể sử dụng toán tử == bên ngoài phạm vi lớp học. Trong trường hợp đó, bạn có thể tạo các tình trạng quá tải cần thiết hoặc tạo ra quá trình tổng quát bằng các mẫu.

2

Câu hỏi lớn ở đây là - làm thế nào để bạn xác định sự bình đẳng?

Có thể so sánh bất kỳ đối tượng nào với bất kỳ đối tượng nào khác trong cấu trúc phân cấp không? Chỉ có thể so sánh các đối tượng cùng loại? Tiêu chí để so sánh trực tiếp ở đâu?

Việc triển khai giải pháp sẽ phụ thuộc vào câu trả lời cho các câu hỏi này.

1

Sẽ không có ý nghĩa khi có cùng một người bằng hai nhân viên khác nhau nhưng đó là những gì bạn thiết kế cho phép.Bạn tốt hơn là sắp xếp cho danh tính được gắn liền với một người. Sau đó bạn hỏi a.identity() == b.identity().

1

Để thực hiện operator== đối xứng, bạn phải có một người và người lao động với các chi tiết được chia sẻ cùng một khác nhau sao cho:

Person p("Foo"); 
Employee e("Foo" , 1); 
p == e; // false 
e == p; // false 

Đây là unintuitive nhưng cần thiết.

Để thực hiện điều này, bạn có thể sử dụng typeid keyword

bool operator==(const Person& other) const 
{ 
    return m_Name == other.m_Name && typeid(other) == typeid(*this); 
} 

Tất nhiên Person phải là một kiểu đa hình (có ít nhất một chức năng ảo).

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