2010-11-17 59 views
9
class Material 
{ 
public: 
void foo() 
{ 
    cout << "Class Material"; 
} 
}; 

class Unusual_Material : public Material 
{ 
public: 
void foo() 
{ 
    cout << "Class Unusual_Material"; 
} 
}; 

int main() 
{ 
Material strange = Unusual_Material(); 
strange.foo(); //outputs "Class Material" 

return 0; 
} 

Tôi muốn điều này dẫn đến "Class Unusual_Material" được hiển thị trên bảng điều khiển. Có cách nào tôi có thể đạt được điều này? Trong chương trình của tôi, tôi có một tài liệu lớp mà từ đó các tài liệu cụ thể khác được bắt nguồn. Phương thức Material :: foo() đại diện cho một phương thức trong Material đủ cho hầu hết các vật liệu, nhưng một cách khác, foo() khác cần phải được định nghĩa cho một vật liệu có tính chất bất thường.Gọi phương thức lớp dẫn xuất từ ​​tham chiếu lớp cơ sở

Tất cả các đối tượng trong chương trình của tôi đều chứa trường Material. Trong trường hợp họ được chỉ định một tài liệu bất thường, tôi muốn có nguồn gốc, bất thường foo được gọi.

Điều này có thể hoặc là khá dễ dàng hoặc không thể, nhưng tôi không thể tìm ra theo cách nào.

Cảm ơn

+1

Là một lưu ý, mã như 'Chất liệu lạ = Unusual_Material();' có thể dẫn đến các vấn đề cắt đối tượng: http://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c – birryree

Trả lời

19

gì bạn muốn là đa hình, và để kích hoạt nó cho một hàm bạn cần để làm cho nó virtual:

class Material 
{ 
public: 
    virtual void foo() // Note virtual keyword! 
    { 
     cout << "Class Material"; 
    } 
}; 

class Unusual_Material : public Material 
{ 
public: 
    void foo() // Will override foo() in the base class 
    { 
     cout << "Class Unusual_Material"; 
    } 
}; 

Ngoài ra, đa hình chỉ hoạt động cho tài liệu tham khảo và gợi ý:

int main() 
{ 
    Unusual_Material unusualMaterial; 
    Material& strange = unusualMaterial; 
    strange.foo(); 
    return 0; 
} 

/* OR */ 

int main() 
{ 
    Unusual_Material unusualMaterial; 
    Material* strange = &unusualMaterial; 
    strange->foo(); 
    return 0; 
} 

Nội dung bạn có trong đoạn mã của mình sẽ là slice the Unusual_Material object:

int main() 
{ 
    // Unusual_Material object will be sliced! 
    Material strange = Unusual_Material(); 
    strange.foo(); 
    return 0; 
} 
+1

Ah! Cảm ơn bạn đã chỉ ra rằng. Tôi đoán tôi đã quên rằng ảo không chỉ định nghĩa một lớp trừu tượng. Cảm ơn bạn đã phản hồi nhanh chóng! – user487100

+1

@ user487100: Không sao, miễn là bạn nhận ra điều gì đã xảy ra. Tôi khuyên bạn nên chọn [một cuốn sách C++ tốt] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list), vì nó sẽ bao gồm chủ đề cơ bản này trong chi tiết hơn nhiều. –

+0

Và tôi cũng không biết gì về việc cắt. Tôi nghĩ rằng chương trình sẽ không có quyền truy cập vào các phần có nguồn gốc, nhưng tôi đoán, khi không sử dụng một tham chiếu, điều đó có ý nghĩa rất nhiều. Cảm ơn bạn đã thêm bit đó vào cuối để tôi chỉnh sửa. – user487100

1

Tuy nhiên lời giải thích tốt hơn sẽ là ..

class Base 
{ 
public: 
void foo()  //make virtual void foo(),have derived method invoked 
{ 
    cout << "Class Base"; 
} 
}; 
class Derived: public Base 
{ 
public: 
void foo() 
{ 
    cout << "Class Derived"; 
} 
}; 
int main() 
{ 
Base base1 = Derived(); 
Base1.foo(); //outputs "Class Base" 
      // Base object, calling base method 

Base *base2 = new Derived(); 
Base2->foo(); //outputs"Class Base",Again Base object calling base method 

// But to have base object, calling Derived method, following are the ways 
// Add virtual access modifier for base foo() method. Then do as below, to //have derived method being invoked. 
// 
// Base *base2 = new Derived(); 
// Base2->foo(); //outputs "Class Derived" . 

return 0; 
} 
Các vấn đề liên quan