在另一个 class 中使用时链接 class

Linking a class when used inside another class

当我有一个 class 我想在其他地方使用时,例如 Secondaryfile.cpp,我可以将它很好地导入另一个文件,在那里我创建一个新的 class,只要正如我在 .cpp 文件而不是头文件中执行 class 定义等,否则我会收到链接错误。我尝试在 Secondaryfile.cpp 中添加 extern "C" 之类的内容,但无济于事。查看错误,我也认为也许我不应该使用命名空间,但是,仍然会导致相同的错误。

我这样做的原因是我想将一个 Tertiaryfile 导入到 Mainfile 中,它有一个与 Secondaryfile 中的函数同名的函数,所以我希望能够将它们称为 Secondaryfile::add1()Tertiaryfile::add1(),并通过使用名称空间避免任何具有相同名称的问题。我希望能够在其头文件中声明 Mainfile class,以便我可以导入它并在不同的 class 中使用它。

在下面的示例中,运行 g++ Mainfile2.cpp 编译正常,但是,g++ Mainfile.cpp 没有,而是导致以下错误:

Mainfile.cpp:(.text+0x20): undefined reference to 'Secondaryfile::Secondaryfile::Secondaryfile()'
Mainfile.cpp:(.text+0x58): undefined reference to 'Secondaryfile::Secondaryfile::getX()'
Mainfile.cpp:(.text+0x7a): undefined reference to 'Secondaryfile::Secondaryfile::Secondaryfile(int)'

我的代码: Mainfile.cpp

#include "Mainfile.h"
#include <cstddef>
#include <cstdio>

Mainfile::Mainfile(char* name, Secondaryfile::Secondaryfile x)
{
    this->name = name;
    this->x = x;
}

Mainfile::getDoubleX(){
    return this->x.getX() * 2;
}

static Secondaryfile::Secondaryfile getObj(int num){
    return Secondaryfile::Secondaryfile(num);
}

int main(){

}

Mainfile.h

#ifndef MAINFILE_H
#define MAINFILE_H

namespace Secondaryfile{
    #include "Secondaryfile.h"
}

class Mainfile
{
 
public:
    char* name;
    Secondaryfile::Secondaryfile x;

    Mainfile(char*, Secondaryfile::Secondaryfile);

    int getDoubleX();
    static Secondaryfile::Secondaryfile getObj(int);

};

#endif 

Mainfile2.cpp

namespace Secondaryfile{
    #include "Secondaryfile.h"
}
#include "Mainfile2.h"
#include <cstddef>
#include <cstdio>

class Mainfile2{
    public:
        char* name;
        Secondaryfile::Secondaryfile x;

        Mainfile2(char* name, Secondaryfile::Secondaryfile x)
        {
            this->name = name;
            this->x = x;
        }

        getDoubleX(){
            return this->x.getX() * 2;
        }

        static Secondaryfile::Secondaryfile getObj(int num){
            return Secondaryfile::Secondaryfile(num);
        }
};

int main(){

}

Mainfile2.h

#ifndef MAINFILE2_H
#define MAINFILE2_H



int getDoubleX();
static Secondaryfile::Secondaryfile getObj(int);

#endif 

Secondaryfile.cpp

#include "Secondaryfile.h"
#include <cstddef>
#include <cstdio>

Secondaryfile::Secondaryfile(int x)
{
    this->x = x;
}
Secondaryfile::Secondaryfile()
{
    this->x = 0;
}

int Secondaryfile::getX()
{
    return this->x;
}


int Secondaryfile::add1(int num)
{
    return num+1;
}

int main(){

}

Secondaryfile.h

#ifndef SECONDARYFILE_H
#define SECONDARYFILE_H

class Secondaryfile
{
 
public:
    int x;

    Secondaryfile();
    Secondaryfile(int);

    int getX();
    static int add1(int);

};

#endif 

你的代码有很多问题。

  1. 在Mainfile.cpp中你没有指定return类型的Mainfile::getDoubleX()(应该是int

  2. 您只能在 class 定义中指定 static 成员函数(在 Mainfile.cpp 中,函数 getObj 具有该限定符)。另外它应该有一个 class 范围,所以正确的写法是 Secondaryfile Mainfile::getObj(int num)

  3. 正在做 namespace Secondaryfile{ #include "Secondaryfile.h"}。你不应该这样做。源文件中的 #include "Secondaryfile.h" 就足够了。你提到你这样做是为了防止“链接错误”,但这可能是因为你的代码和项目配置中的其他问题。

  4. 您也没有指定您的编译器和 IDE/cmake/makefile 配置,这对于正确编译和链接这些头文件和源文件是 必不可少的

  5. 您是在构建库还是可执行代码?您在源文件中包含一个不执行任何操作的 main() 函数,这也是不好的做法,因为 C++ 中的 main() 是一个 entry-point 函数,这意味着编译器将看起来让它创建程序的起点1.

考虑到这些,我尝试修复您的代码。看看这是不是您想要的:

Mainfile.cpp

//
// Created by vinicius on 21/10/2020.
//

#include "Mainfile.h"
#include <cstddef>
#include <cstdio>

Mainfile::Mainfile(char* name, Secondaryfile x)
{
    this->name = name;
    this->x = x;
}

int Mainfile::getDoubleX(){
    return this->x.getX() * 2;
}

Secondaryfile Mainfile::getObj(int num){

    return Secondaryfile(num);
}

int main() {
    //Test code
    printf("Hello World!\n--------\n");
    Secondaryfile s = Secondaryfile();
    Mainfile f = Mainfile("myname", s);
    Secondaryfile myobj = f.getObj(12);
    printf("Value = %d", myobj.getX());
}

Mainfile.h

//
// Created by vinicius on 21/10/2020.
//

#ifndef MAINFILE_H
#define MAINFILE_H


#include "Secondaryfile.h"


class Mainfile
{

public:
    char* name;
    Secondaryfile x;

    Mainfile(char*, Secondaryfile);

    int getDoubleX();
    static Secondaryfile getObj(int);

};

#endif

Mainfile2.cpp

//
// Created by vinicius on 21/10/2020.
//


#include "Secondaryfile.h"

#include "Mainfile2.h"
#include <cstddef>
#include <cstdio>

Secondaryfile Mainfile2::getObj(int num) {
    return Secondaryfile(num);
}

int Mainfile2::getDoubleX() {
    return this->x.getX() * 2;
}

Mainfile2::Mainfile2(char *name, Secondaryfile x) {
    this->name = name;
    this->x = x;
}

Mainfile2.h

//
// Created by vinicius on 21/10/2020.
//

#ifndef MAINFILE2_H
#define MAINFILE2_H





class Mainfile2{
public:
    char* name;
    Secondaryfile x;

    Mainfile2(char* name, Secondaryfile x);

    int getDoubleX();

    static Secondaryfile getObj(int num);
};

#endif

Secondaryfile.cpp

//
// Created by vinicius on 21/10/2020.
//

#include "Secondaryfile.h"
#include <cstddef>
#include <cstdio>

Secondaryfile::Secondaryfile(int x)
{
    this->x = x;
}

Secondaryfile::Secondaryfile()
{
    this->x = 0;
}

int Secondaryfile::getX()
{
    return this->x;
}

int Secondaryfile::add1(int num)
{
    return num+1;
}

Secondaryfile.h

//
// Created by vinicius on 21/10/2020.
//

#ifndef SECONDARYFILE_H
#define SECONDARYFILE_H

class Secondaryfile
{

public:
    int x;

    Secondaryfile();
    Secondaryfile(int);

    int getX();
    static int add1(int);

};

#endif

以及项目的 CMakeLists.txt(在 CLion 中制作):

cmake_minimum_required(VERSION 3.17)
project(secfile)

set(CMAKE_CXX_STANDARD 14)

include_directories(.)

add_executable(secfile
        Mainfile.cpp
        Mainfile.h
        Mainfile2.cpp
        Mainfile2.h
        Secondaryfile.cpp
        Secondaryfile.h)

用cmake构建项目后,就可以运行了。这样做之后,它输出以下行:

Hello World!
--------
Value = 12

符合预期。


1 https://en.cppreference.com/w/cpp/language/main_function