2016-02-25 64 views
5
// SomeOtherClass.hpp 
#pragma once 

int someOtherCallMe(); 

class SomeOtherClass { 
    public: 

    static int callMe() { 
     static int _instance = 7; 
     ++_instance; 
     return _instance; 
    } 
}; 


// SomeOtherClass.cpp 
#include "SomeOtherClass.hpp" 

int 
someOtherCallMe() { 
    return SomeOtherClass::callMe(); 
} 

// main.cpp 

#include "SomeOtherClass.hpp" 

#include <iostream> 

int 
main() { 

    std::cout << SomeOtherClass::callMe(); 
    std::cout << someOtherCallMe(); 

    return 0; 
} 

Tôi có ba tệp: SomeOtherClass.hpp/cpp, main.cpp. Các tệp đó dẫn đến hai tệp nhị phân: thư viện được chia sẻ (của SomeOtherClass.cpp) và tệp thực thi (của main.cpp, được liên kết với thư viện được chia sẻ).Biến tĩnh C++ trong các phương thức lớp tĩnh được xác định trong tiêu đề

Không C++ bảo đảm rằng static <any-type> _instance sẽ là một biến duy nhất trong quá trình thực hiện chương trình (không quan trọng trong số lượng nhị phân được xác định)?

Lưu ý Để làm rõ tình huống. Sự nhầm lẫn mà tôi thấy trong tình huống này là, một mặt, SomeOtherClass::callMe được định nghĩa trong chương trình hai lần, được mong đợi (vì hàm thành viên tĩnh lớp thực sự là một hàm bình thường với liên kết bên trong, nếu chúng được định nghĩa tại chỗ, như trong này trường hợp), và đó là những gì bạn có thể thấy từ việc tháo gỡ. Vì chúng ta có hai hàm với các biến địa phương tĩnh trong mã máy. Ngôn ngữ/tiêu chuẩn đủ điều kiện hành vi của họ như thế nào?

+0

Khi sử dụng MS Visual Studio, bạn sẽ cần sử dụng đúng '__declspec' khi tạo DLL và sử dụng DLL để nó hoạt động. –

+0

Vâng, tôi biết ơn vì điều đó. – user14416

+0

Nếu câu hỏi thực sự là về các biến tĩnh trên các ranh giới DLL thì cần được đề cập trong tiêu đề và nổi bật hơn trong văn bản –

Trả lời

0

Có. Một tĩnh sẽ là một giá trị duy nhất. Rất nhiều thứ khác không được xác định rõ hoặc là mới đối với tiêu chuẩn. (Khi nào chúng được khởi tạo nếu chúng là toàn cầu? Là mã để khởi tạo tĩnh trong một hàm có an toàn không?) Nhưng, vâng, bạn có thể tin cậy vào đó chỉ có một.

Chỉ làm rõ ở đây ngoài tiêu chuẩn nhưng tầm quan trọng thực tế nếu bạn đang tạo thư viện được chia sẻ (.so hoặc .dll): Bạn không thể liên kết thư viện lớp C++ của mình thành thư viện được chia sẻ. Nếu không, điều đó sẽ tạo hai bản sao nếu bạn làm điều này trong hai thư viện được chia sẻ khác nhau. (Nhận xét này áp dụng cho mọi thứ về thư viện, không chỉ các biến tĩnh. Nếu bạn làm điều này, thì có sự trùng lặp của mọi thứ.)

Chỉnh sửa: Trên nhiều nền tảng (như Linux và Windows), điều này có thể được sử dụng để cố ý "ẩn" biến tĩnh của bạn. Nếu bạn không làm cho hàm/lớp của bạn có thể truy cập được bên ngoài dll/như vậy (sử dụng declspec hoặc thuộc tính hiển thị), thì bạn có thể đảm bảo dll của bạn/do đó có bản sao riêng của toàn bộ lớp. Kỹ thuật này có thể giúp giảm tương tác không mong muốn giữa các thư viện. Tuy nhiên, trong trường hợp của bạn, có vẻ như bạn thực sự chỉ muốn một, điều này sẽ xảy ra nếu lớp của bạn có khả năng hiển thị thích hợp trong tất cả các thư viện của bạn (chỉ hiển thị trong một thư viện và các thư viện khác liên kết với thư viện đó).

Sửa lần nữa để tham khảo các tiêu chuẩn

Nếu một hàm với mối liên hệ bên ngoài được khai báo nội tuyến trong một đơn vị dịch thuật, nó phải được khai báo inline trong tất cả các đơn vị dịch trong đó nó xuất hiện; không cần chẩn đoán. Một hàm nội tuyến có liên kết bên ngoài sẽ có cùng địa chỉ trong tất cả các đơn vị dịch. Biến cục bộ tĩnh trong hàm nội tuyến bên ngoài luôn đề cập đến cùng một đối tượng.

7.1.2.4, C++ 14

+0

Bất kỳ nhận xét nào, tại sao nó lại bị bỏ qua? – user14416

+0

Kính gửi Rob, cảm ơn vì nỗ lực, câu trả lời của bạn dường như gần gũi nhất với những gì tôi muốn bây giờ, tôi thực sự không biết tại sao bạn lại bị downvoted, mb bạn đã viết smth lạ ngay từ đầu, tôi đã không xem xét tại lịch sử thay đổi thực sự, hoặc mb nó chỉ là người đọc stackoverflow cẩu thả bất cứ điều gì. Tôi sẽ đánh giá cao nó nếu bạn có thể đưa ra một số tham chiếu đến tiêu chuẩn và/hoặc một số nguồn lực đáng tin cậy, và loại liên kết đó là gì, và cách tiêu chuẩn/ngôn ngữ hội đủ điều kiện loại cấu trúc này .. – user14416

+0

Tôi nghĩ rằng tôi đã bỏ phiếu bởi vì nó là một chủ đề phức tạp rất khó trả lời với có/không. Tôi cũng đã làm rõ thêm sau khi tôi đã được bình chọn. Tôi không nghĩ rằng có bất cứ điều gì trong tiêu chuẩn để bao gồm dlls và chia sẻ nhị phân. Các thông tin là từ một dự án dẫn (tôi), những người đã quản lý một sản phẩm với hàng chục dlls và rất nhiều nhà phát triển. Chúng tôi đã thực hiện và học được từ tất cả những sai lầm này. Điểm mấu chốt: nếu nó được chia sẻ, xác định nó một nơi nào đó, xuất khẩu nó phải, và trình biên dịch sẽ chăm sóc phần còn lại. –

1

Does C++ guaranties that static _instance will be a single variable during the execution of a program (does not matter in how many binaries it was defined)?

Tôi không nghĩ rằng ngôn ngữ có gì để nói về điều đó. Nó không nói về các thư viện tĩnh hoặc các thư viện động.

Đó là trách nhiệm của việc triển khai nhằm cung cấp cơ chế để đảm bảo rằng có thể có một định nghĩa. Đó là tùy thuộc vào người dùng để đảm bảo rằng họ sử dụng cơ chế được cung cấp bởi việc triển khai để có một định nghĩa về biến số static trong hàm.

+0

Tôi đồng ý với bạn rằng người dùng chọn tùy chọn muốn và thực hiện bằng phương tiện ngôn ngữ . Nhưng trong tình huống này tôi sẽ nói rằng vì hàm tĩnh ('SomeOtherClass :: callMe') được nhân đôi trong mã. Hơn so với biến tĩnh nên được nhân đôi hoặc, nhưng nó không phải là ít nhất với g + +. Nhưng mặt khác, nó không nên được nhân đôi bởi vì như ngôn ngữ nói 'static' guaranties đối tượng duy nhất. – user14416

Các vấn đề liên quan