Php tạo đối tượng động

Chúng tôi sử dụng cookie để cung cấp cho bạn trải nghiệm duyệt web tốt hơn, phân tích lưu lượng truy cập trang web và cá nhân hóa nội dung. Đọc về cách chúng tôi sử dụng cookie và cách bạn có thể kiểm soát chúng trong Chính sách cookie của chúng tôi. Nếu bạn tiếp tục sử dụng trang web này, bạn đồng ý với việc chúng tôi sử dụng cookie

Đây là một trong những câu hỏi thường gặp trong buổi phỏng vấn. Hầu hết các ứng viên đều đạt thứ nhất, và một số thứ hai, thứ ba và có thể là thứ 4 nữa. Nhưng hiếm khi họ giải quyết vấn đề thứ 5

  1. Một biến được khai báo tĩnh trong phần thân của hàm duy trì giá trị của nó giữa các lần gọi hàm
  2. Một biến được khai báo là tĩnh trong một mô-đun (nhưng bên ngoài phần thân của hàm) có thể được truy cập bởi tất cả các hàm trong mô-đun đó. Tuy nhiên, nó không thể truy cập được bằng các chức năng từ các mô-đun khác
  3. các thành viên tĩnh tồn tại với tư cách là thành viên của lớp chứ không phải là một thể hiện trong mỗi đối tượng của lớp. Chỉ có một phiên bản duy nhất của mỗi thành viên dữ liệu tĩnh cho toàn bộ lớp
  4. Các hàm thành viên không tĩnh có thể truy cập tất cả các thành viên dữ liệu của lớp. tĩnh và không tĩnh.
    Các hàm thành viên tĩnh chỉ có thể hoạt động trên các thành viên dữ liệu tĩnh.
  5. Các hàm C được khai báo tĩnh trong một mô-đun chỉ có thể được gọi bởi các hàm khác trong mô-đun đó (phạm vi tệp)

Đối tượng tĩnh là đối tượng tồn tại từ khi nó được tạo cho đến khi kết thúc chương trình. Vì vậy, các đối tượng ngăn xếp và đống được loại trừ. Nhưng các đối tượng toàn cầu, các đối tượng ở phạm vi không gian tên, các đối tượng được khai báo tĩnh bên trong các lớp/hàm và các đối tượng được khai báo ở phạm vi tệp được bao gồm trong các đối tượng tĩnh. Các đối tượng tĩnh bị hủy khi chương trình ngừng chạy

Các biến được xác định bên ngoài hàm hoặc bằng cách sử dụng từ khóa tĩnh có thời lượng lưu trữ tĩnh. Chúng tồn tại trong toàn bộ thời gian chạy của một chương trình

Các biến này có thể được phân loại thành ba nhóm về mặt liên kết

  1. liên kết bên ngoài
  2. liên kết nội bộ
  3. không có liên kết

Vì các biến tĩnh giữ nguyên trong suốt vòng đời của chương trình nên chúng dễ dàng xử lý đối với hệ thống bộ nhớ và chúng được phân bổ trong một khối bộ nhớ cố định

Dưới đây là một ví dụ về các biến tĩnh với thời lượng khác nhau

int a= 1;
static int b = 2;
int main() {}
void f() {
	static int c = 3;
	int d = 4;
}

Tất cả các biến tĩnh tồn tại cho đến khi chương trình kết thúc. Biến d có phạm vi cục bộ và không có liên kết - nó không được sử dụng bên ngoài f(). Nhưng c vẫn còn trong bộ nhớ ngay cả khi chức năng f() không được thực thi. Bằng cách nói rằng c là tĩnh, chúng ta đang nói rằng chúng ta muốn phân bổ nó một lần và chỉ một lần, tại một thời điểm nào đó trước khi hàm f() được gọi lần đầu tiên và chúng ta không muốn phân bổ nó miễn là chương trình của chúng ta

Cả a và b đều có thể được truy cập từ điểm khai báo cho đến khi kết thúc tệp. Nhưng a có thể được sử dụng trong các tệp khác vì nó có liên kết bên ngoài

Tất cả các biến thời lượng tĩnh có các đặc điểm khởi tạo sau

  1. Một biến tĩnh chưa được khởi tạo được đặt thành 0
  2. Một biến tĩnh chỉ có thể được khởi tạo với một biểu thức hằng
int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}

Trong C ++ đã mang lại một chút thay đổi cho các lớp lưu trữ mặc định. Mặc dù biến toàn cục có liên kết bên ngoài theo mặc định, const toàn cầu có liên kết bên trong theo mặc định. Nói cách khác, C++ xử lý một định nghĩa const toàn cầu như thể tĩnh đã được sử dụng như trong đoạn mã sau

const int a = 10;
int main() { ... 

Vì vậy, "const int a = 10" trở thành "static const int a = 10". Tuy nhiên, nếu const toàn cầu có liên kết bên ngoài như các biến thông thường, khai báo const sẽ là lỗi vì chúng ta chỉ có thể định nghĩa một biến toàn cục trong một tệp. Nói cách khác, chỉ một tệp có thể chứa khai báo trước và các tệp khác phải cung cấp khai báo tham chiếu bằng từ khóa bên ngoài. Lưu ý rằng chỉ những khai báo không có extern mới có thể khởi tạo giá trị

Tuy nhiên, nếu chúng ta muốn tạo một hằng số có liên kết bên ngoài, chúng ta có thể sử dụng từ khóa bên ngoài để ghi đè lên liên kết bên trong mặc định

extern const int a = 20;

Ở đây, chúng ta nên sử dụng từ khóa extern để khai báo hằng trong tất cả các tệp có sử dụng hằng. Đó là sự khác biệt giữa các biến bên ngoài thông thường và hằng số. Đối với các biến ngoài thông thường, chúng tôi không sử dụng từ khóa extern khi xác định một biến, nhưng chúng tôi sử dụng extern trong các tệp khác sử dụng biến đó

Một khai báo bên ngoài không xác định biến trừ khi nó cũng được khởi tạo trong cùng một câu lệnh

extern int x;       // declaration
extern int x = 10;  // definition

Đối với chữ "C" bên ngoài, vui lòng truy cập

Lưu trữ tĩnh và phân bổ động

Bộ nhớ động được điều khiển bởi các toán tử mới và xóa, không phải bởi phạm vi và quy tắc liên kết. Vì vậy, bộ nhớ động có thể được cấp phát từ một chức năng và được giải phóng khỏi chức năng khác

Mặc dù sơ đồ lưu trữ không áp dụng cho bộ nhớ động, nhưng áp dụng cho các biến con trỏ tĩnh và tự động được sử dụng để theo dõi bộ nhớ động

Hãy nhìn vào dòng mã sau đây

int *ptr = new int[10];

40 byte bộ nhớ được phân bổ bởi bộ nhớ mới vẫn còn trong bộ nhớ cho đến khi xóa giải phóng nó. Nhưng con trỏ ptr chuyển từ sự tồn tại khi hàm chứa khai báo này kết thúc

Nếu chúng ta muốn có sẵn 40 byte bộ nhớ được phân bổ từ một chức năng khác, chúng ta cần chuyển hoặc trả lại địa chỉ của nó cho chức năng đó

Mặt khác, nếu chúng ta khai báo ptr với liên kết ngoài, con trỏ ptr sẽ khả dụng bằng cách sử dụng.
extern int *ptr;

Tuy nhiên, một câu lệnh sử dụng new to set ptr phải nằm trong một hàm vì các biến lưu trữ tĩnh chỉ có thể được khởi tạo với các biểu thức hằng số như trong ví dụ sau

int *ptr;
// initialization with non-const not allowed here
// int *ptr = new int[10];	
int main() 
{
	ptr = new int[10];
...

Xem Phân bổ bộ nhớ

Các thành viên tĩnh tồn tại với tư cách là thành viên của lớp chứ không phải là một thể hiện trong mỗi đối tượng của lớp. Vì vậy, từ khóa này không có sẵn trong hàm thành viên tĩnh. Các chức năng như vậy chỉ có thể truy cập các thành viên dữ liệu tĩnh. Có một thể hiện duy nhất của mỗi thành viên dữ liệu tĩnh cho toàn bộ lớp, cần được khởi tạo, thường là trong tệp nguồn thực hiện các hàm thành viên của lớp. Bởi vì thành viên được khởi tạo bên ngoài định nghĩa lớp, chúng ta phải sử dụng tên đủ điều kiện khi chúng ta khởi tạo nó

________số 8

Đây là ví dụ thực tế, Xe hơi. h

class Car
{
private:
	static int id;
public:
 	Car();
...
};

Hồ sơ thực hiện, Ô tô. cpp

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
0

Mã khởi tạo thành viên id tĩnh thành 100. Một lần nữa lưu ý rằng chúng ta không thể khởi tạo biến thành viên tĩnh bên trong khai báo lớp. Đó là bởi vì phần khai báo là một mô tả về cách cấp phát bộ nhớ, nhưng nó không cấp phát bộ nhớ. Chúng tôi phân bổ và khởi tạo bộ nhớ bằng cách tạo một đối tượng sử dụng định dạng đó

Trong trường hợp thành viên lớp tĩnh, chúng tôi khởi tạo thành viên tĩnh một cách độc lập, với một câu lệnh riêng bên ngoài khai báo lớp. Đó là bởi vì thành viên lớp tĩnh được lưu trữ riêng chứ không phải là một phần của đối tượng

Ngoại lệ đối với việc khởi tạo thành viên dữ liệu tĩnh bên trong khai báo lớp là nếu thành viên dữ liệu tĩnh là hằng số của kiểu tích phân hoặc kiểu liệt kê

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
1

Ví dụ sau đây cho thấy quyền truy cập bất hợp pháp vào thành viên không tĩnh từ một hàm tĩnh

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
2

Trong hàm f(), x=z là một lỗi vì f(), một hàm tĩnh, đang cố truy cập thành viên không tĩnh x

Vì vậy, sửa chữa nên như thế này

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
3

Không thể sử dụng các thành viên không tĩnh làm đối số mặc định

Đoạn mã sau cho thấy không thể sử dụng thành viên không tĩnh làm đối số mặc định

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
4

Dưới đây là một số đặc điểm của các hàm thành viên tĩnh

  1. Hàm thành viên tĩnh chỉ có thể truy cập dữ liệu thành viên tĩnh, hàm thành viên tĩnh và dữ liệu và hàm bên ngoài lớp. Vì vậy, chúng ta phải lưu ý không sử dụng hàm thành viên tĩnh theo cách tương tự như hàm thành viên không tĩnh, vì hàm thành viên không tĩnh có thể truy cập tất cả những điều trên bao gồm cả thành viên dữ liệu tĩnh
  2. Trước tiên chúng ta phải hiểu khái niệm về dữ liệu tĩnh trong khi tìm hiểu ngữ cảnh của các hàm tĩnh. Có thể khai báo một thành viên dữ liệu của một lớp là tĩnh bất kể nó là kiểu công khai hay kiểu riêng tư trong định nghĩa lớp. Nếu một dữ liệu được khai báo là tĩnh, thì dữ liệu tĩnh chỉ được tạo và khởi tạo một lần. Các thành viên dữ liệu không tĩnh được tạo đi tạo lại. Đối với mỗi đối tượng riêng biệt của lớp, dữ liệu tĩnh chỉ được tạo và khởi tạo một lần. Như trong khái niệm dữ liệu tĩnh, tất cả các đối tượng của lớp trong các hàm tĩnh đều chia sẻ các biến. Điều này áp dụng cho tất cả các đối tượng của lớp
  3. Hàm thành viên không tĩnh chỉ có thể được gọi sau khi khởi tạo lớp dưới dạng đối tượng. Đây không phải là trường hợp với các hàm thành viên tĩnh. Một hàm thành viên tĩnh có thể được gọi, ngay cả khi một lớp không được khởi tạo
  4. Một hàm thành viên tĩnh không thể có quyền truy cập vào con trỏ this của lớp
  5. Hàm thành viên không tĩnh có thể được khai báo là ảo nhưng phải cẩn thận để không khai báo hàm thành viên tĩnh là ảo

Tĩnh - Mẫu Singleton

Mẫu thiết kế Singleton là một ví dụ điển hình về hàm thành viên tĩnh và biến thành viên tĩnh. Trong mẫu này, chúng tôi đặt hàm tạo trong phần riêng tư không phải trong phần chung của một lớp. Vì vậy, chúng ta không thể truy cập hàm tạo để tạo một thể hiện của lớp. Thay vào đó, chúng tôi đặt một hàm công khai là hàm tĩnh. getInstance() sẽ chỉ tạo một phiên bản một lần. Lưu ý rằng nếu phương thức này không phải là tĩnh, thì không có cách nào để gọi phương thức getInstance() mặc dù đó là phương thức công khai. Đó là bởi vì chúng tôi không có bất kỳ phiên bản Singleton nào

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
5

Đầu ra là

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
6

Liên kết bên ngoài và từ khóa tĩnh

Liên kết bên ngoài có nghĩa là một biểu tượng trong một đơn vị dịch thuật có thể được truy cập từ các đơn vị dịch thuật khác. Trừ khi chúng ta thực hiện các bước đặc biệt, các hàm và biến toàn cục trong. cpp sẽ có liên kết bên ngoài

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
7

Đây là mã có thể truy cập My_CONSTANT, My_NAME và My_Function() mà không cần sử dụng giao diện công khai, do đó phá vỡ tính đóng gói

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
8

Một cách để tránh vấn đề liên kết này là sử dụng từ khóa tĩnh

int x;               // x set to 0
int y = 50;          // 50 is literal constant
int z = sizeof(int); // sizeof ok
int zz = 10 * x;     // not allowed, x is not constant
int main() 
{...}
9

Mặc dù chúng ta có thể tránh được vấn đề liên kết bên ngoài bằng cách sử dụng từ khóa tĩnh nhưng nó vẫn có vấn đề gây ô nhiễm không gian tên toàn cầu. Vì vậy, giải pháp cho người đánh bóng là sử dụng không gian tên ẩn danh như hình bên dưới