Làm cách nào để triển khai các hàm thành viên lớp tĩnh trong tệp * .cpp?


125

Có thể triển khai staticcác hàm thành viên lớp trong tệp * .cpp thay vì thực hiện trong tệp tiêu đề không?

Có phải tất cả các staticchức năng luôn luôn inlinekhông?


4
Bạn có thể giải thích tại sao bạn "KHÔNG THỂ" triển khai hàm memeber lớp tĩnh trong tệp cpp của mình không? bất kỳ lỗi? Nó thường không có giới hạn về nơi bạn triển khai chức năng đó.
mùa đôngTTr

7
@winterTTr, Câu hỏi có thể nảy sinh vì hầu hết các ví dụ / hướng dẫn trên web không trình bày một ví dụ triển khai riêng, thay vào đó khai báo và xác định nó trong tiêu đề. Ít nhất sáu lần truy cập đầu tiên trong công cụ tìm kiếm yêu thích của tôi cho "Hàm thành viên tĩnh C ++" đều làm theo cách này và không giải thích cách bạn triển khai nó trong các tệp riêng biệt cho người mới làm quen.
crobar

8
Khi bạn triển khai, không lặp lại statictừ khóa. Chỉ viết statictừ khóa trong định nghĩa lớp trong tệp tiêu đề
SomethingSomething

@crobar, bạn nói đúng rằng có rất ít ví dụ về nhiều tệp. Tôi đấu tranh để tìm ra này, vì vậy tôi quyết định chia sẻ những điều sau đây:
Don McLachlan

Câu trả lời:


154

Nó là.

test.hpp:

class A {
public:
    static int a(int i);
};

test.cpp:

#include <iostream>
#include "test.hpp"


int A::a(int i) {
    return i + 2;
}

using namespace std;
int main() {
    cout << A::a(4) << endl;
}

Không phải lúc nào chúng cũng nội tuyến, nhưng trình biên dịch có thể tạo ra chúng.


47

Thử cái này:

header.hxx:

class CFoo
{
public: 
    static bool IsThisThingOn();
};

class.cxx:

#include "header.hxx"
bool CFoo::IsThisThingOn() // note: no static keyword here
{
    return true;
}

9

helper.hxx

class helper
{
 public: 
   static void fn1 () 
   { /* defined in header itself */ }

   /* fn2 defined in src file helper.cxx */
   static void fn2(); 
};

helper.cxx

#include "helper.hxx"
void helper::fn2()
{
  /* fn2 defined in helper.cxx */
  /* do something */
}

A.cxx

#include "helper.hxx"
A::foo() {
  helper::fn1(); 
  helper::fn2();
}

Để biết thêm về cách c ++ xử lý các hàm tĩnh, hãy truy cập: Các hàm thành viên tĩnh trong c ++ có được sao chép trong nhiều đơn vị dịch không?


2

Có, bạn có thể xác định các hàm thành viên tĩnh trong tệp * .cpp. Nếu bạn xác định nó trong tiêu đề, trình biên dịch theo mặc định sẽ coi nó là nội tuyến. Tuy nhiên, nó không có nghĩa là các bản sao riêng biệt của hàm thành viên tĩnh sẽ tồn tại trong tệp thực thi. Vui lòng theo dõi bài đăng này để tìm hiểu thêm về điều này: Các hàm thành viên tĩnh trong c ++ có được sao chép trong nhiều đơn vị dịch không?


Nếu bạn xác định nó trong phần thân của lớp, nó sẽ tự động được mặc định. Nếu nó nằm trong tiêu đề bên ngoài nội dung lớp, tốt hơn hết nó nên được đánh dấu inlinehoặc templatehoặc bạn sẽ nhận được nhiều lỗi định nghĩa từ trình liên kết.
Ben Voigt

2

Trong tệp tiêu đề của bạn, hãy nói foo.h

class Foo{
    public:
        static void someFunction(params..);
    // other stuff
}

Trong tệp triển khai của bạn, nói foo.cpp

#include "foo.h"

void Foo::someFunction(params..){
    // Implementation of someFunction
}

Rất quan trọng

Chỉ cần đảm bảo rằng bạn không sử dụng từ khóa static trong chữ ký phương thức khi bạn đang triển khai hàm tĩnh trong tệp triển khai của mình.

Chúc may mắn


1

@crobar, bạn nói đúng rằng có rất ít ví dụ về nhiều tệp, vì vậy tôi quyết định chia sẻ những điều sau đây với hy vọng nó sẽ giúp ích cho những người khác:

::::::::::::::
main.cpp
::::::::::::::

#include <iostream>

#include "UseSomething.h"
#include "Something.h"

int main()
{
    UseSomething y;
    std::cout << y.getValue() << '\n';
}

::::::::::::::
Something.h
::::::::::::::

#ifndef SOMETHING_H_
#define SOMETHING_H_

class Something
{
private:
    static int s_value;
public:
    static int getValue() { return s_value; } // static member function
};
#endif

::::::::::::::
Something.cpp
::::::::::::::

#include "Something.h"

int Something::s_value = 1; // initializer

::::::::::::::
UseSomething.h
::::::::::::::

#ifndef USESOMETHING_H_
#define USESOMETHING_H_

class UseSomething
{
public:
    int getValue();
};

#endif

::::::::::::::
UseSomething.cpp
::::::::::::::

#include "UseSomething.h"
#include "Something.h"

int UseSomething::getValue()
{
    return(Something::getValue());
}


0

Các #includechỉ thị theo nghĩa đen có nghĩa là "sao chép tất cả dữ liệu trong file đó vào chỗ này." Vì vậy, khi bạn bao gồm tệp tiêu đề, nó ở dạng văn bản trong tệp mã và mọi thứ trong đó sẽ ở đó, cung cấp hoặc có hiệu lực của các lệnh khác hoặc thay thế macro, khi tệp mã (bây giờ được gọi là đơn vị biên dịch hoặc đơn vị dịch ) chuyển từ mô-đun tiền xử lý sang mô-đun trình biên dịch.

Điều đó có nghĩa là khai báo và định nghĩa về hàm thành viên tĩnh của bạn thực sự nằm trong cùng một tệp ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.