现在将C++类拆分为文件将无法编译

phy*_*ael 1 c++ split compilation class

我正在教自己用C++编写类,但似乎无法完成编译.如果你能帮助我弄清楚不仅如何,而且为什么,我将非常感激.先感谢您!这是我的三个文件:

make_pmt.C

#include <iostream>
#include "pmt.h"

using namespace std;


int main() {
    CPMT *pmt = new CPMT;
    pmt->SetVoltage(900);
    pmt->SetGain(2e6);

    double voltage = pmt->GetVoltage();
    double gain= pmt->GetGain();

    cout << "The voltage is " << voltage
         << " and the gain is " << gain << "." <<endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

pmt.C

#include "pmt.h"

using namespace std;

class CPMT {
    double gain, voltage;
    public:
        double GetGain() {return gain;}
        double GetVoltage() {return voltage;}

        void SetGain(double g) {gain=g;}
        void SetVoltage(double v) {voltage=v;}
};
Run Code Online (Sandbox Code Playgroud)

pmt.h

#ifndef PMT_H
#define PMT_H 1

using namespace std;

class CPMT {
    double gain, voltage;
    public:
        double GetGain();
        double GetVoltage();

        void SetGain(double g);
        void SetVoltage(double v);
};

#endif
Run Code Online (Sandbox Code Playgroud)

作为参考,我得到一个链接器错误(对吗?):

Undefined symbols:
  "CPMT::GetVoltage()", referenced from:
      _main in ccoYuMbH.o
  "CPMT::GetGain()", referenced from:
      _main in ccoYuMbH.o
  "CPMT::SetVoltage(double)", referenced from:
      _main in ccoYuMbH.o
  "CPMT::SetGain(double)", referenced from:
      _main in ccoYuMbH.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

Edd*_*onk 6

pmt.C看起来像这样:

#include "pmt.h"

using namespace std;

double CPMT::GetGain() {return gain;}
double CPMT::GetVoltage() {return voltage;}

void CPMT::SetGain(double g) {gain=g;}
void CPMT::SetVoltage(double v) {voltage=v;}
Run Code Online (Sandbox Code Playgroud)

我编译它像这样:

g++ make_pmt.C pmt.C
Run Code Online (Sandbox Code Playgroud)

您还需要添加构造函数并初始化增益和电压.


sbi*_*sbi 6

首先是一些分类法.
这个

class CPMT {
    public:
        double GetGain();
        // ...
};
Run Code Online (Sandbox Code Playgroud)

定义一个类而不定义成员函数.这个

class CPMT {
    public:
        double GetGain() {return gain;}
        // ...
};
Run Code Online (Sandbox Code Playgroud)

定义同一个类,同时定义其成员函数(隐式)内联.这个

double CPMT::GetGain() {return gain;}
// ...
Run Code Online (Sandbox Code Playgroud)

定义成员函数(不是内联).

现在,如果要将实现与接口分开,则标头需要定义类,而实现文件需要定义其成员函数.所以纯类定义

class CPMT {
    public:
        double GetGain();
        //...
};
Run Code Online (Sandbox Code Playgroud)

进入头文件和实现

double CPMT::GetGain() {return gain;}
// ...
Run Code Online (Sandbox Code Playgroud)

进入实现文件 - 除了那些你想要内联实现的成员函数.由于inline要求编译器将函数的实现替换为每次调用它,因此必须在调用函数的位置存在实现.这就是为什么内联函数的实现必须在头文件中.

内联成员函数有两种方法.一种是在类的定义中定义它

class CPMT {
    public:
        double GetGain() {return gain;}
        // ...
};
Run Code Online (Sandbox Code Playgroud)

这隐含了它inline.另一种是明确地内联它

class CPMT {
    public:
        double GetGain();
        //...
};

inline double CPMT::GetGain() {return gain;}
// ...
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,实现必须在头文件中.