2009-03-27 28 views
5

Tôi có một hệ thống phân cấp các lớp. Lớp cơ sở sử dụng một số tham số điều chỉnh có thể tải từ tệp (và có thể tải lại trong thời gian chạy). Mỗi lớp dẫn xuất có thể thêm một số tham số bổ sung. Tôi đang tìm một cách để phân bổ một mảng thông số có kích thước chính xác trong constructor cơ sở, do đó tôi không phải deallocate và tái phân bổ trong lớp dẫn xuất. Tôi đã hy vọng cho một cái gì đó như thế này, nhưng nó không làm việc (thông số luôn có 2 yếu tố):Làm thế nào để phân bổ mảng trong constructor cơ sở với kích thước dựa trên lớp dẫn xuất?

class Base 
    { static int nParms; 
    virtual int getNParms() { return nParms;} 
    float *parameters; 
    public: 
    Base() 
    { parameters= new float[this->getNParms()]; 
     parameters[0] = globalReloadableX; 
     parameters[1] = globalReloadableY; 
    } 
    }; 
    int Base::nParams =2; 

    class Derived : public Base 
    { static int nParms; 
    virtual int getNParms() { return nParms;} 
    public: 
    Derived() : Base() 
    { parameters[2] = globalReloadableZ; 
    } 
    } 
    int Derived::nParams =3; 

Tôi đã nhìn thấy this question, nhưng giải pháp đó không thực hiện khá công việc cho tôi. Tôi cũng đã cố gắng tạo tham số cho một mảng thông thường trong mỗi lớp:

class Base 
    { float parameters[2] 
    ... 
    class Derived : public Base 
    { float parameters[3] 
    ... 

nhưng điều đó làm cho Derived có 2 mảng riêng biệt.

Bất kỳ ý tưởng nào?

Trả lời

5

Tại sao không vượt qua kích thước mảng bắt buộc làm tham số trong hàm tạo của lớp cơ sở?

(Lý do chức năng ảo không gọi lớp có nguồn gốc là bởi vì đó là cách C++ chức năng ảo làm việc;. Khái niệm, cho đến khi các nhà xây dựng lớp có nguồn gốc hoàn tất, loại của đối tượng vẫn là lớp cơ sở)

+0

Tại sao không? Quá rõ ràng! Đôi khi tôi chỉ nhận được quá quấn lên trong các chi tiết ... Cảm ơn bạn đã giải thích lý do tại sao. – AShelly

+0

Không vấn đề gì xảy ra với mọi người! –

2

Điều gì về làm cho kích thước một tham số?

class Base 
{ static int nParms; 
    virtual int getNParms() { return nParms;} 
    float *parameters; 
public: 
    Base(int n = nParams) 
    { parameters= new float[n]; 
    parameters[0] = globalRelodableX; 
    parameters[1] = globalRelodableY; 
    } 
}; 
int Base::nParams =2; 

class Derived : public Base 
{ static int nParms; 
    virtual int getNParms() { return nParms;} 
public: 
    Derived() : Base(nParams) 
    { parameters[2] = globalRelodableZ; 
    } 
} 
int Derived::nParams =3; 
2

Tại sao nên sử dụng mảng? Các std :: vector sẽ cho phép bạn sử dụng nhiều tham số khi cần thiết trong lớp dẫn xuất, với cơ sở không biết (hoặc quan tâm) bao nhiêu nó cần.

+0

Đó là một điểm tốt. Tôi thực sự đang sử dụng vectơ ở những nơi khác. Nhưng tôi vẫn làm hầu hết công việc của mình trong C, vì vậy tôi có xu hướng tìm hiểu những gì tôi biết khi tôi thêm các tính năng ... – AShelly

0

Tôi sẽ xem xét sử dụng sơ đồ :: std. Nó có thể phát triển với cơ sở và có nguồn gốc cả hai không quan tâm về số lượng các tham số khác sử dụng. Cặp khóa/giá trị có thể dễ dàng hơn trong việc quản lý các chỉ mục số đó, mặc dù đó rõ ràng là phụ thuộc ứng dụng.

0

Tôi thích cả câu trả lời của Earwicker và Steve, tùy thuộc vào những gì bắt buộc. Nếu có nhiều đối tượng trong số này được tạo ra và bị phá hủy thường xuyên, thì bạn muốn có lượng phân bổ bộ nhớ tối thiểu có thể, và do đó Earwicker cao hơn. Tuy nhiên, nếu đây là thứ thường được "tạo ra và hiếm khi được tái tạo" thì tôi sẽ đi với câu trả lời của Steve, vì bản đồ thường dễ làm việc hơn và phát triển năng động khi cần thiết, nhưng có lẽ quá nhiều chi phí nếu đối tượng này là một cái gì đó đang được thực hiện và phá hủy rất nhiều.

2

Bạn có thể biến nó thành tham số cho hàm tạo, như được đề xuất bởi người khác, nhưng bạn cũng có thể tạo Base cho lớp mẫu, với kích thước là tham số. Điều này có nhiều lợi thế, chẳng hạn như loại bỏ nhu cầu mảng được phân bổ trên heap:

template <size_t nParams> 
class Base 
{ 
    float parameters[nParams]; 
public: 
    Base() 
    { // could use a static_assert(nParams > 1) here... 
     parameters[0] = globalRelodableX; 
     parameters[1] = globalRelodableY; 
    } 
}; 

class Derived : public Base<3> // or whatever 
{ 
public: 
    Derived() 
    { parameters[2] = globalRelodableZ; } 
}; 
Các vấn đề liên quan