未定义的参考成员函数 [英] Undefined Reference To Member function

查看:142
本文介绍了未定义的参考成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



以下是有这个问题的两个类:

  // Username.h 

#ifndef USERNAME_H
#define USERNAME_H

#include< ;串GT;
使用namespace std;

class用户名{
private:
字符串名称;
public:
Username(string =);
string getName()const;
void setName(string);
};

#endif

...

...

  // Username.cpp 

#includeUsername.h

用户名::用户名(字符串n):Name(n){}
字符串用户名:: getName()const {返回名称;}
用户名:: setName(string n){Name = n;}

...

  // User.h 

#ifndef USER_H
#define USER_H

#include< string>
#includeUsername.h
using namespace std;

class用户{
保护:
用户名* UserUsername;
public:
User(string s);
virtual〜User();
用户名* getUsername()const;
void setUsername(Username *);
};

#endif

...

...

  // User.cpp 

#includeUser.h

User :: User(string s):UserUsername(新用户名){}

用户::〜用户(){}

用户名:: User :: getUsername()const {return UserUsername ;}

无用户:: setUsername(用户名* u){UserUsername = u;}

int main(){return 0;}

如果我使用g ++ User.cpp进行编译,则会出现以下错误:

  /tmp/ccEmWmfl.o:在函数User :: User(std :: basic_string< char,std :: char_traits< char> ;, std :: allocator< char>> )':

User.cpp :(。text + 0x3e):对用户名::用户名(std :: basic_string< char,std :: char_traits< char> ;, std :: allocator< ; char>>)'

collect2:ld返回1退出状态

如果我使用g ++ User.cpp Username.cpp -o main,或者如果我使用内联构造函数/析构函数,则不会出错。



这些类很容易,但我需要编译的东西超过一个类。



我是使用g ++编译Ubuntu shell的新手,所以请问,有人可以帮我理解吗?

解决方案


g ++ User.cpp


编译User.cpp并尝试从中创建可执行文件(即,调用链接程序)。由于User.cpp在User.cpp中没有完全定义一个符号(这里的用户名构造函数:

  User :: User(string s):UserUsername(新用户名){} 

符号有望在链接阶段通过结合生成的所有cpp的所有生成目标文件输出并将缺失符号拼接在一起来完成链接。在这里,您不告诉g ++如何找到cpp以外的用户名构造函数的完整定义与主,所以它的失败。



然而,这:


g ++用户.cpp Username.cpp -o main


告诉链接器在哪里找到完整的用户名定义(在通过编译用户名生成的目标文件中。因此,链接可以通过使用Username.cpp中定义的内容来匹配未在User.cpp中定义的标识符,从而成功填充缺失的部分。



您可能会认为 - 我已经告诉过了通过包含头文件来编译它,它应该知道!。你所做的是声明的符号。你已经做出了承诺,最终将定义一些东西,无论是在编译这个cpp期间,还是在后来将它与通过编译另一个cpp生成的另一个目标文件链接起来。 g ++需要知道你打算从何处取出所有定义,以便它能正确构建最终的可执行文件。


I'm trying to solve a compiling problem regarding outside defined constructor.

Here's 2 of the classes that have this problem:

//Username.h

#ifndef USERNAME_H
#define USERNAME_H

#include <string>
using namespace std;

class Username{
private:
    string Name;
public:
    Username(string = "");
    string getName() const;
    void setName(string);
};

#endif

...

//Username.cpp

#include "Username.h"

Username::Username(string n):Name(n){}
string Username::getName() const{return Name;}
void Username::setName(string n){Name = n;}

...

//User.h

#ifndef USER_H
#define USER_H

#include <string>
#include "Username.h"
using namespace std;

class User{
protected:
        Username* UserUsername;
public:
    User(string s);
    virtual ~User();
    Username* getUsername() const;
    void setUsername(Username*);
};

#endif

...

//User.cpp

#include "User.h"

User::User(string s):UserUsername(new Username(s)){}

User::~User(){}

Username* User::getUsername() const{return UserUsername;}

void User::setUsername(Username* u){UserUsername=u;}

int main(){return 0;}

If I compile using "g++ User.cpp" I get this error:

/tmp/ccEmWmfl.o: In function `User::User(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)':

User.cpp:(.text+0x3e): undefined reference to `Username::Username(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'

collect2: ld returned 1 exit status

If I use "g++ User.cpp Username.cpp -o main" or if I use inline constructors/destructors I get no error.

These classes are very easy, but I have tons more to compile that require more than one class.

I'm new at compiling in Ubuntu shell with g++, so please, can someone help me to understand?

解决方案

g++ User.cpp

This compiles User.cpp and attempts to create an executable from it (ie the linker is invoked). Since User.cpp has a symbol not fully defined in User.cpp (the Username constructor here:

User::User(string s):UserUsername(new Username(s)){}

the symbol is expected to be defined at the link stage. Linking is done by combining all the generated object file output of all the cpps you generated and piecing together the missing symbols. Here you're not telling g++ about where to find the full definition of the Username constructor other than the cpp with main, so its failing.

This, however:

g++ User.cpp Username.cpp -o main

Tells the linker where to find full Username definitions (in the object file generated by compiling Username.cpp). So linking can succeed in filling in the missing pieces by using whats defined in Username.cpp to match up identifiers not defined in User.cpp.

You may think -- "well I've told the compiler about it by including the header file, it should know!". What you've done is declared the symbol. You've made a promise that something will eventually be defined, either during compilation of that one cpp or by later linking it with another object file generated by compiling another cpp. g++ needs to know where you intend to pull all your definitions from so it can build a final executable correctly.

这篇关于未定义的参考成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆