วิธีใช้ฟังก์ชันสมาชิกคลาสแบบคงที่ในไฟล์ * .cpp


125

เป็นไปได้หรือไม่ที่จะใช้staticฟังก์ชันสมาชิกคลาสในไฟล์ * .cpp แทนที่จะทำในไฟล์ส่วนหัว

ทุกstaticฟังก์ชันเสมอกันinlineหรือไม่?


4
คุณช่วยอธิบายได้ไหมว่าทำไมคุณ "ไม่สามารถ" ใช้ฟังก์ชัน memeber คลาสแบบคงที่ในไฟล์ cpp ของคุณ ข้อผิดพลาดใด ๆ โดยปกติจะไม่มีข้อ จำกัด เกี่ยวกับตำแหน่งที่คุณใช้ฟังก์ชันดังกล่าว
winterTTr

7
@winterTTr คำถามอาจเกิดขึ้นเนื่องจากตัวอย่าง / บทช่วยสอนส่วนใหญ่บนเว็บไม่ได้นำเสนอตัวอย่างการใช้งานแยกต่างหากแทนที่จะประกาศและกำหนดไว้ในส่วนหัว อย่างน้อยหกครั้งแรกในเครื่องมือค้นหาที่ฉันชื่นชอบสำหรับ "ฟังก์ชันสมาชิกคงที่ C ++" ทั้งหมดทำในลักษณะนี้และไม่ได้อธิบายวิธีการใช้งานในไฟล์แยกต่างหากสำหรับมือใหม่
crobar

8
เมื่อคุณใช้งานอย่าใช้staticคำหลักซ้ำ เขียนstaticคีย์เวิร์ดเฉพาะในนิยามคลาสในไฟล์ส่วนหัว
SomethingSomething

@crobar คุณคิดถูกแล้วที่มีตัวอย่างหลายไฟล์มากมาย ฉันพยายามที่จะคิดออกดังนั้นฉันจึงตัดสินใจแบ่งปันสิ่งต่อไปนี้:
Don Mclachlan

คำตอบ:


154

มันคือ.

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;
}

พวกเขาไม่ได้อยู่ในบรรทัดเสมอไป แต่คอมไพเลอร์สามารถสร้างได้


47

ลองสิ่งนี้:

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();
}

หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ c ++ จัดการกับฟังก์ชันคงที่เยี่ยมชม: ฟังก์ชันสมาชิกแบบคงที่ใน c ++ ถูกคัดลอกในหน่วยการแปลหลายหน่วยหรือไม่


2

ใช่คุณสามารถกำหนดฟังก์ชันสมาชิกแบบคงที่ในไฟล์ * .cpp หากคุณกำหนดไว้ในส่วนหัวคอมไพเลอร์จะถือว่าเป็นอินไลน์ตามค่าเริ่มต้น อย่างไรก็ตามไม่ได้หมายความว่าจะมีสำเนาของฟังก์ชันสมาชิกแบบคงที่แยกต่างหากในไฟล์ปฏิบัติการ โปรดติดตามโพสต์นี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับเรื่องนี้: ฟังก์ชันสมาชิกแบบคงที่ใน c ++ ถูกคัดลอกในหน่วยการแปลหลายหน่วยหรือไม่?


หากคุณกำหนดไว้ในส่วนเนื้อหาคลาสจะเป็นค่าเริ่มต้นโดยอัตโนมัติ ถ้าเป็นในส่วนหัวชั้นนอกร่างกายมันได้ดีกว่าถูกทำเครื่องหมายอย่างใดอย่างหนึ่งinlineหรือtemplateหรือคุณจะได้รับข้อผิดพลาดความหมายหลายรายการจากลิงเกอร์
Ben Voigt

2

ในไฟล์ส่วนหัวของคุณพูดว่าfoo.h

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

ในไฟล์การนำไปใช้งานของคุณให้พูดว่าfoo.cpp

#include "foo.h"

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

สำคัญมาก

ตรวจสอบให้แน่ใจว่าคุณไม่ได้ใช้คีย์เวิร์ดแบบคงที่ในลายเซ็นวิธีของคุณเมื่อคุณใช้ฟังก์ชันคงที่ในไฟล์การนำไปใช้งานของคุณ

โชคดี


1

@crobar คุณคิดถูกแล้วที่มีตัวอย่างหลายไฟล์ไม่เพียงพอดังนั้นฉันจึงตัดสินใจแบ่งปันสิ่งต่อไปนี้ด้วยความหวังว่าจะช่วยผู้อื่น:

::::::::::::::
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

#includeสั่งความหมายว่า "คัดลอกข้อมูลทั้งหมดที่อยู่ในแฟ้มที่จุดนี้". ดังนั้นเมื่อคุณรวมไฟล์ส่วนหัวมันจะเป็นข้อความภายในไฟล์โค้ดและทุกอย่างจะอยู่ที่นั่นให้หรือใช้ผลของคำสั่งอื่น ๆ หรือการแทนที่มาโครเมื่อไฟล์โค้ด (ปัจจุบันเรียกว่าหน่วยคอมไพล์หรือหน่วยแปล ) คือ ส่งออกจากโมดูลพรีโปรเซสเซอร์ไปยังโมดูลคอมไพเลอร์

ซึ่งหมายความว่าการประกาศและคำจำกัดความของฟังก์ชันสมาชิกแบบคงที่ของคุณอยู่ในไฟล์เดียวกันตลอดมา ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.