在另一个 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
你的代码有很多问题。
在Mainfile.cpp中你没有指定return类型的Mainfile::getDoubleX()(应该是int
)
您只能在 class 定义中指定 static
成员函数(在 Mainfile.cpp 中,函数 getObj
具有该限定符)。另外它应该有一个 class 范围,所以正确的写法是 Secondaryfile Mainfile::getObj(int num)
正在做 namespace Secondaryfile{ #include "Secondaryfile.h"}
。你不应该这样做。源文件中的 #include "Secondaryfile.h"
就足够了。你提到你这样做是为了防止“链接错误”,但这可能是因为你的代码和项目配置中的其他问题。
您也没有指定您的编译器和 IDE/cmake/makefile 配置,这对于正确编译和链接这些头文件和源文件是 必不可少的 。
您是在构建库还是可执行代码?您在源文件中包含一个不执行任何操作的 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
符合预期。
当我有一个 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
你的代码有很多问题。
在Mainfile.cpp中你没有指定return类型的Mainfile::getDoubleX()(应该是
int
)您只能在 class 定义中指定
static
成员函数(在 Mainfile.cpp 中,函数getObj
具有该限定符)。另外它应该有一个 class 范围,所以正确的写法是Secondaryfile Mainfile::getObj(int num)
正在做
namespace Secondaryfile{ #include "Secondaryfile.h"}
。你不应该这样做。源文件中的#include "Secondaryfile.h"
就足够了。你提到你这样做是为了防止“链接错误”,但这可能是因为你的代码和项目配置中的其他问题。您也没有指定您的编译器和 IDE/cmake/makefile 配置,这对于正确编译和链接这些头文件和源文件是 必不可少的 。
您是在构建库还是可执行代码?您在源文件中包含一个不执行任何操作的
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
符合预期。