2008-11-12 17 views
21

Điều này liên quan đến một số câu hỏi khác, chẳng hạn như: this và một số câu hỏi khác của tôi.Làm thế nào để bạn khai báo mảng trong tiêu đề C++?

Trong this question, và những người khác, chúng ta thấy chúng ta có thể khai báo và khởi tạo mảng chuỗi trong một bước tốt đẹp, ví dụ:

const char* const list[] = {"zip", "zam", "bam"}; //from other question 

Điều này có thể được thực hiện trong việc thực hiện một chức năng không có bận tâm, hoặc trong phần thân của tệp .cpp, bên ngoài phạm vi bất kỳ.

Những gì tôi muốn làm là để có một mảng như thế này như là thành viên của một lớp Tôi đang sử dụng, một cái gì đó như thế này:

class DataProvider : public SomethingElse 
{ 
    const char* const mStringData[] = {"Name1", "Name2", "Name3", ... "NameX"}; 

public: 
    DataProvider(); 
    ~DataProvider(); 

    char* GetData() 
    { 
     int index = GetCurrentIndex(); //work out the index based on some other data 
     return mStringData[index]; //error checking and what have you omitted 
    } 

}; 

Nhưng, trình biên dịch phàn nàn và tôi dường như không thể làm việc tại sao. Có thể khai báo và khởi tạo một mảng như thế này trong một bước trong định nghĩa lớp không? Có lựa chọn thay thế nào tốt hơn không?

Tôi chắc chắn đây là một sai lầm rất nghiệp dư, nhưng như mọi khi, sự giúp đỡ và lời khuyên của bạn được đánh giá cao.

Chúc mừng,

xan

+0

"implimentation" nên được đánh vần là "thực hiện" –

Trả lời

18

Sử dụng khởi tạo tĩnh và bên ngoài từ khóa để làm cho mảng một thành viên tĩnh của lớp:

Trong tập tin tiêu đề:

class DataProvider : public SomethingElse 
{ 
    static const char* const mStringData[]; 

public: 
    DataProvider(); 
    ~DataProvider(); 

    const char* const GetData() 
    { 
     int index = GetCurrentIndex(); //work out the index based on some other data 
     return mStringData[index]; //error checking and what have you omitted 
    } 

}; 

Trong.cpp file:

const char* const DataProvider::mStringData[] = {"Name1", "Name2", "Name3", ... "NameX"}; 
+0

Bạn cần cung cấp cho mảng một kích thước trong khai báo tiêu đề. – mbyrne215

+0

Bạn có chắc chắn không? Nó làm việc tốt cho tôi (Visual C++ 2005) và tôi đã sử dụng nó trước đó một vài lần. Trừ khi nó là hành vi không xác định trong tiêu chuẩn (mà tôi sẽ không nhìn lên bây giờ), tôi tin rằng nó sẽ làm việc. –

+0

Bạn ổn khi đang sử dụng trình khởi tạo. Trình biên dịch sẽ tính toán kích thước dựa trên số lượng các mục trong bộ khởi tạo. –

3

này là không thể trong C++. Bạn không thể trực tiếp khởi tạo mảng. Thay vào đó bạn phải cung cấp cho nó kích thước nó sẽ có (4 trong trường hợp của bạn), và bạn phải khởi tạo mảng trong constructor của DataProvider:

class DataProvider { 
    enum { SIZEOF_VALUES = 4 }; 
    const char * values[SIZEOF_VALUES]; 

    public: 
    DataProvider() { 
     const char * const v[SIZEOF_VALUES] = { 
      "one", "two", "three", "four" 
     }; 
     std::copy(v, v + SIZEOF_VALUES, values); 
    } 
}; 

Lưu ý rằng bạn phải từ bỏ trên const-Ness của con trỏ trong mảng, vì bạn không thể trực tiếp khởi tạo mảng. Nhưng bạn cần phải thiết lập các con trỏ tới các giá trị đúng, và do đó các con trỏ cần phải được sửa đổi.

Nếu giá trị của bạn trong mảng là const tuy nhiên, cách duy nhất là sử dụng một mảng tĩnh:

/* in the header file */ 
class DataProvider { 
    enum { SIZEOF_VALUES = 4 }; 
    static const char * const values[SIZEOF_VALUES]; 
}; 

/* in cpp file: */ 

const char * const DataProvider::values[SIZEOF_VALUES] = 
    { "one", "two", "three", "four" }; 

Có mảng tĩnh có nghĩa là tất cả các đối tượng sẽ chia sẻ mảng đó. Do đó bạn cũng sẽ lưu bộ nhớ.

+1

_ "Có mảng tĩnh có nghĩa là tất cả các đối tượng sẽ chia sẻ rằng mảng" _ Mà cũng có nghĩa là bạn đã có khả năng chỉ bị tổn hại các nguyên tắc cơ bản của lập trình hướng đối tượng . –

3

Lý do bạn không thể khai báo mảng của bạn như thế (const char * []) ​​là:

  • bạn không thể có initializers trong khai báo lớp, vv
  • cú pháp const char* [] không chỉ ra bao nhiêu không gian mà trình biên dịch cần phân bổ cho mỗi cá thể (mảng của bạn được khai báo là biến mẫu).

Bên cạnh đó, bạn có thể muốn làm cho mảng đó tĩnh, vì nó thực chất là một giá trị không đổi.

+0

Thực ra, 'const char * []' _does_ cho biết bao nhiêu không gian mà trình biên dịch cần phân bổ cho mỗi cá thể - chỉ là một con trỏ tới bộ nhớ. Điều này thực sự _why_ khai báo mảng tĩnh không được phép cho các biến không tĩnh; mỗi cá thể mới yêu cầu cấp phát bộ nhớ bổ sung và loại xử lý trên không đó được xử lý một cách rõ ràng trong các nhà xây dựng. – meustrus