2010-08-20 46 views
45

Có thể khởi tạo giá trị const tĩnh bên ngoài của hàm tạo không? Nó có thể được khởi tạo tại cùng một nơi mà các tờ khai thành viên được tìm thấy không?Cách khởi tạo thành viên const tĩnh trong C++?

class A { 
private: 
    static const int a = 4; 
    /*...*/ 
}; 
+8

Có, những gì bạn có (nhưng chỉ dành cho các loại tích phân). – UncleBens

+3

Chỉ muốn thêm rằng 'static' không liên quan gì đến các hàm tạo vì các thành viên' static' không cụ thể cho một cá thể đã cho và tồn tại bên ngoài nó. – ereOn

+0

Trong thực tế, bạn * phải * khởi tạo const statics bên ngoài một hàm tạo lớp. Nếu không nó sẽ không phải là một const tĩnh. DUCY? –

Trả lời

54

CÓ bạn chỉ có thể cho các loại int. Nếu bạn muốn thành viên tĩnh của bạn là bất kỳ loại nào khác, bạn sẽ phải xác định nó ở đâu đó trong tệp cpp.

class A{ 
private: 
static const int a = 4; // valid 
static const std::string t ; // can't be initialized here 
... 
... 
}; 


// in a cpp file where the static variable will exist 
const std::string A::t = "this way it works"; 

Ngoài ra, lưu ý rằng quy tắc này đã bị xóa trong C++ 11, bây giờ (với một trình biên dịch cung cấp các tính năng), bạn có thể khởi tạo những gì bạn muốn trực tiếp trong việc kê khai thành viên lớp.

+0

tại sao static const double = value; không hoạt động? – anarhikos

+2

@anarhikos - khởi tạo trong lớp chỉ hoạt động cho các loại tích phân. 'double' không phải là một loại tích phân. –

+1

@anrhikos: Đó là lý do tại sao bạn không nên xác định bên trong lớp học. Bạn nên xác định bên ngoài lớp học như là một vấn đề thực tế (xem câu trả lời của tôi) –

27

Static data members (C++ only)

Việc kê khai của một thành viên dữ liệu tĩnh trong danh sách thành viên của một lớp không phải là một định nghĩa. Bạn phải định nghĩa thành viên tĩnh bên ngoài khai báo lớp, trong phạm vi không gian tên. Ví dụ:

class X 
{ 
public: 
     static int i; 
}; 
int X::i = 0; // definition outside class declaration 

Khi bạn xác định thành viên dữ liệu tĩnh, nó tồn tại mặc dù không có đối tượng tồn tại của lớp dữ liệu tĩnh tồn tại. Trong ví dụ trên, không có đối tượng nào của lớp X tồn tại mặc dù thành viên dữ liệu tĩnh X :: i đã được định nghĩa.

Thành phần dữ liệu tĩnh của một lớp trong phạm vi không gian tên có liên kết bên ngoài. Trình khởi tạo cho một thành viên dữ liệu tĩnh nằm trong phạm vi của lớp khai báo thành viên.

Thành viên dữ liệu tĩnh có thể thuộc bất kỳ loại nào ngoại trừ khoảng trống hoặc khoảng trống đủ điều kiện với const hoặc dễ bay hơi. Bạn không thể khai báo một thành viên dữ liệu tĩnh là có thể thay đổi được.

Bạn chỉ có thể có một định nghĩa về thành viên tĩnh trong chương trình. Các lớp, lớp chưa được đặt tên trong các lớp chưa đặt tên và các lớp địa phương không thể có các thành viên dữ liệu tĩnh.

Thành viên dữ liệu tĩnh và người khởi tạo của họ có thể truy cập các thành viên riêng tư và được bảo vệ khác trong lớp học của họ. Ví dụ sau đây cho thấy làm thế nào bạn có thể khởi tạo các thành viên tĩnh nhờ sủ dụng các thành viên tĩnh khác, mặc dù các thành viên là cá nhân:

class C { 
     static int i; 
     static int j; 
     static int k; 
     static int l; 
     static int m; 
     static int n; 
     static int p; 
     static int q; 
     static int r; 
     static int s; 
     static int f() { return 0; } 
     int a; 
public: 
     C() { a = 0; } 
     }; 

C c; 
int C::i = C::f(); // initialize with static member function 
int C::j = C::i;  // initialize with another static data member 
int C::k = c.f();  // initialize with member function from an object 
int C::l = c.j;  // initialize with data member from an object 
int C::s = c.a;  // initialize with nonstatic data member 
int C::r = 1;   // initialize with a constant value 

class Y : private C {} y; 

int C::m = Y::f(); 
int C::n = Y::r; 
int C::p = y.r;  // error 
int C::q = y.f();  // error 

các initializations của C :: p và C :: q nguyên nhân sai lầm vì y là một đối tượng của một lớp có nguồn gốc riêng từ C, và các thành viên của nó không thể truy cập được đối với các thành viên của C.

Nếu thành viên dữ liệu tĩnh là loại tách rời hoặc kiểu liệt kê, bạn có thể chỉ định bộ khởi tạo không đổi trong khai báo thành viên dữ liệu tĩnh. Bộ khởi tạo hằng số này phải là một biểu thức hằng số không thể thiếu. Lưu ý rằng bộ khởi tạo không đổi không phải là định nghĩa. Bạn vẫn cần xác định thành viên tĩnh trong một không gian tên bao quanh. Ví dụ sau đây minh họa điều này:

#include <iostream> 
using namespace std; 

struct X { 
    static const int a = 76; 
}; 

const int X::a; 

int main() { 
    cout << X::a << endl; 
} 

Mã thông báo = 76 ở cuối khai báo thành viên dữ liệu tĩnh a là bộ khởi tạo không đổi.

0

Nếu tôi nhớ chính xác, bạn không thể xác định nó bên trong lớp học. Bạn rõ ràng cần xác định nó bên ngoài như được đề cập bởi pablo.

3

Bạn không thể khởi tạo thành viên tĩnh trong các nhà thầu. Các kiểu tích phân bạn có thể khởi tạo nội tuyến tại khai báo của chúng. Các thành viên tĩnh khác phải được xác định (trong tệp .cpp):

// .h 
class A{ 
private: 
static const int a = 4; 
static const foo bar; 
... 
... 
}; 

// .cpp 
const foo A::bar = ...; 
10

Chỉ vì mục đích hoàn chỉnh, tôi sẽ thêm vào các biến thành viên mẫu tĩnh.

template<class T> struct X{ 
    static T x; 
}; 

template<class T> T X<T>::x = T(); 

int main(){ 
    X<int> x; 
} 
Các vấn đề liên quan