2014-09-02 12 views
6

Tôi muốn tiêm một số thông tin cơ bản vào một lớp dẫn xuất mà nó có thể xây dựng trên đó. Lớp dẫn xuất không nên quan tâm đến việc khởi tạo các thông tin đó, nó chỉ nên ở đó.Có cách nào để tạo một cá thể có nguồn gốc từ một cá thể cơ bản không?

Điều đó một mình sẽ dễ dàng có thể thông qua kế thừa. Nhưng vấn đề là lớp cơ sở không biết giá trị của riêng nó. Thay vào đó, chúng cần được chuyển thành tham số. Tuy nhiên, vì lớp dẫn xuất không cần phải quan tâm đến điều đó, việc tạo đường hầm cho các tham số thông qua các hàm tạo có nguồn gốc gọi là hàm tạo cơ bản với nó là không có tùy chọn.

Giải pháp duy nhất tôi có thể nghĩ là làm cho thông tin có sẵn tĩnh để lớp cơ sở có thể nhận được chúng mà không cần trợ giúp. Nhưng tôi muốn tránh điều đó.

Có cách nào để tạo và khởi tạo lớp cơ sở đầu tiên và mở rộng cá thể thành một kiểu dẫn xuất sau đó không? Nếu không, làm thế nào tôi có thể đạt được thứ tự tạo và phụ thuộc này bằng cách sử dụng các tính năng sẵn có của C++?

#include <string> 
#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base(string name, int age) : name(name), age(age) {} 
protected: 
    const string name; 
    int age = 0; 
}; 

class Derived : public Base { 
    Derived() { // No parameters here, no call to base constructor 
     cout << "My name is " << name << " and I'm " << age << "." << endl; 
    } 
} 

Base base("Peter", 42); 
Derived derived(base); // "My name is Peter and I'm 42." 
+1

"Không có lời gọi đến cơ sở xây dựng" của bạn làm cho tôi trả lời: Không. Đó không phải là cách C++ hoạt động. – Quentin

+1

TL; DR; [Mẫu thử nghiệm] (http://sourcemaking.com/design_patterns/prototype) có thể giúp ích cho trường hợp sử dụng của bạn. –

Trả lời

6

"Những thông tin nên chỉ có mặt ở đó" nghe giống như là nó cho phép hai cách giải thích:

  • Thông tin là trong thực tế liên tục trên toàn cầu và có thể được mã hóa cứng:

    Derived() : Base("Peter", 42) {} 
    
  • Điều bạn thực sự muốn nói là "cơ sở chỉ nên ở đó":

    Derived(const Base & b) : Base(b) {} 
    
+0

Thông tin không thể được mã hóa cứng. Tuy nhiên, tùy chọn thứ hai có vẻ thú vị. Điều đó có sử dụng hàm tạo bản sao mặc định của 'Base' hay tôi phải tự mình thực hiện? – danijar

+0

Nó sẽ sử dụng bản sao mặc định trừ khi bạn cung cấp – Pete

+0

@danijar: Nó sẽ sử dụng bất kỳ nhà xây dựng bản sao nào của 'Cơ sở' được chọn bởi độ phân giải quá tải ... –

3

Một lựa chọn sẽ được sử dụng thành phần, có nghĩa là Base sẽ là một biến thể hiện của Derived:

#include <string> 
#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base(string name, int age) : name(name), age(age) {} 
    const string name() { return name; } 
    int age() { return age; } 
protected: 
    const string name; 
    int age = 0; 
}; 

class Derived { 
    Derived(Base b): base(b) { // No parameters here 
     cout << "My name is " << base.name() << " and I'm " 
      << base.age() << "." << endl; 
    } 

private: 
    Base base;  
} 

Base base("Peter", 42); 
Derived derived(base); // "My name is Peter and I'm 42." 

Chú ý cách Derived không còn kéo dài Base (có lẽ là cái tên sẽ cần phải được thay đổi) và rằng mọi cuộc gọi đến một biến mẫu trong Base bây giờ là một cuộc gọi phương thức.

5

Mở rộng loại đã phân bổ cho loại có nguồn gốc là không thể vì lý do: nếu trường nhập có nguồn gốc được thêm vào, bạn sẽ xác định kích thước chính xác như thế nào?

Cách có thể chỉ là một nhà xây dựng chấp nhận cá thể Base hoặc có thể là operator=.

Tuy nhiên bạn có thể muốn xem xét sử dụng thành phần trên thừa kế trong ví dụ này. Nếu Base chỉ đóng vai trò mẫu cho Derived, đó không phải là một ví dụ hay về mối quan hệ kế thừa.

+0

Tôi xem xét thành phần, nhưng nó cảm thấy sai.Trong ứng dụng của tôi, đó là về các thành phần được cập nhật thường xuyên. Thành phần có nghĩa là các thành phần cụ thể không phải là thành phần nữa mà là các lớp bình thường với "jetpacks". Giải pháp hiện tại của tôi là cung cấp một phương thức 'void initialize()' bổ sung được gọi ra bên ngoài sau khi xây dựng để thiết lập các thành viên. Tuy nhiên, các giá trị không có sẵn trong các nhà xây dựng có nguồn gốc sau đó. – danijar

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