2012-03-02 35 views
5

có lẽ nó siêu dễ dàng, nhưng ai đó có thể cho tôi biết cách tôi có thể gọi hàm tạo của lớp bậc trên với các đối số được tính toán trong hàm tạo của lớp con? một cái gì đó như thế này:C++ gọi hàm tạo siêu lớp với đối số được tính toán

class A{ 
    A(int i, int j); 
}; 

class B : A{ 
    B(int i); 
}; 

B::B(int i){ 
    int complex_calculation_a= i*5; 
    int complex_calculation_b= i+complex_calculation_a; 
    A(complex_calculation_a, complex_calculation_b); 
} 

// chỉnh sửa: i thay đổi nội dung ví dụ để các lớp cha mất hai đối số mà có một mối quan hệ với nhau

Trả lời

4

Nếu bạn không thể diễn tả tính của bạn trong một biểu thức đơn dòng, thêm một chức năng tĩnh, và gọi nó theo cách bạn thường gọi constructor của lớp cha:

class B : A{ 
public: 
    B(int i) : A(calc(i)) {}; 
private: 
    static int calc(int i) { 
     int res = 1; 
     while (i) { 
      res *= i--; 
     } 
     return res; 
    } 
}; 

EDIT trường hợp Nhiều đối số:

class B : A{ 
public: 
    B(int i) : A(calc_a(i), calc_b(i)) {}; 
private: 
    static int calc_a(int i) { 
     int res = 1; 
     while (i) { 
      res *= i--; 
     } 
     return res; 
    } 
    static int calc_b(int i) { 
     int complex_a = calc_a(i); 
     return complex_a+10; 
    } 
}; 
+0

okay - và nếu constructor superclass có một số đối số? – Mat

+0

@Mat Bạn sẽ cần xác định hàm riêng biệt để tính toán giá trị của mỗi tham số mà bạn không thể hoặc không muốn "nội dòng" làm biểu thức. – dasblinkenlight

+0

nhưng các đối số được tính toán có thể phụ thuộc vào nhau - làm thế nào tôi có thể giải quyết điều đó bằng các hàm khác nhau? – Mat

1

Chỉ như thế này:

class A{ 
    A(int i); 
}; 

class B : A{ 
    B(int i); 
}; 

B::B(int i) : A(i*5) { 
} 

Cuộc gọi để constructor của cha mẹ chỉ có thể đến trong danh sách khởi tạo. Điều đó có nghĩa, rằng bất cứ điều gì bạn đang tính toán phải được biết trước B được xây dựng đầy đủ (ví dụ: bạn có thể không gọi một hàm B thành viên, trừ khi static của nó, nhưng chỉ dựa vào các thông số truyền cho B)

+0

okay - trong trường hợp này ví dụ của tôi là xấu. Tôi cần thực hiện một số cuộc gọi hàm, vòng lặp, phân nhánh có điều kiện và cứ tính toán đối số – Mat

+0

@Mat - như tôi đã nói - bạn chỉ có thể thực hiện điều này trong hàm bên ngoài (thành viên toàn cầu hoặc lớp tĩnh hoặc chức năng thành viên của một đối tượng được chuyển đến 'B'). 'B' không tồn tại khi' A' được gọi. – littleadv

3
B::B(int i) 
    : A(i * 5) 
{} 

Với C++ 11, một cách phức tạp hơn là

B::B(int i) 
    : A(([](int x) { return 5 * x; })(i)) 
{} 

Đối với trường hợp phức tạp, một bảo vệ init chức năng là dễ đọc hơn.

1
struct A 
{ 
    A(int); 
}; 

struct B : public A 
{ 
    B() 
     : A(5) // "initialisation list" 
    {} 
}; 

Bạn phải làm điều này trong danh sách, nhưng bạn có thể sử dụng hàm. Chỉnh sửa: Nếu bạn sử dụng hàm, bạn có thể muốn đặt thành một thành viên tĩnh riêng tư của B.

0
class A 
{ 
public: 
    A(int i){} 
}; 


class B : public A 
{ 
public: 
    B(int i):A(i*5){} 
}; 
Các vấn đề liên quan