定义 class 时对 class 的未定义引用

Undefined reference to class when the class is defined

最近,我开始学习C++。已经了解了一些 python,我决定尝试理解指针,但是在尝试编译文件时我 运行 遇到了错误。错误信息有点令人费解,我在上面纠结了一段时间。 SO 上的答案确实提供了一些关于问题的见解,但由于我对 C++ 还是新手,所以我真的不明白如何解决它。我读到这可能是默认构造函数声明的问题,但我不确定要解决什么问题。

#include <cstddef>
#include <iostream>

using namespace std;

class Uinter
    /*
     * Regrouping class for intervals (_Inter class) 
     * offering 3 different methods:
     *  "reunion(int bi, int bs)" -> Unites the interval pointed by "_tete"
     *                               with the one defined by [bi, bs]
     *  "printUinter()"           -> Prints the interval pointed by "_tete"
     *  "contient(int nb)"        -> Returns True if "nb" is present inside
     *                               the intervals, else False. 
     */
    {
        class _Inter
        /*
         * Class representing a single interval.
         * _bi stands for the lower limit of the interval.
         * _bs stands for the upper limit of the interval.
         */
        {
            int _bi, _bs;
            _Inter* _next;
        public:
            _Inter(int, int, _Inter*);
            // Defining getters and setters for the interval.
            void set_bi(int value)
                {_bi = value;}
            void set_bs(int value)
                {_bs = value;}
            void set_next(_Inter* value)
                {_next = value;}
            int get_bi()
                {return _bi;}
            int get_bs()
                {return _bs;}
            _Inter* get_next()
                {return _next;}
        };
        _Inter* _tete;
    public:
        Uinter(): _tete(nullptr){}
        void reunion(int bi, int bs)
            {
            if(_tete == nullptr)
                {
                _Inter new_interval = _Inter(bi, bs, nullptr);
                _tete = &new_interval;
                }
            else
                {
                if(bi < _tete->get_bi())
                    {
                    if (bs < _tete->get_bi())
                        {
                        _Inter new_interval = _Inter(bi, bs, _tete);
                        _tete = &new_interval;
                        }

                    else if (bs > _tete->get_bs())
                        {
                        _Inter new_interval = _Inter(bi, bs, _tete->get_next());
                        _tete = &new_interval;
                        }

                    else if (bs > _tete->get_bi())
                        {
                        _Inter new_interval = _Inter(bi, _tete->get_bs(), _tete->get_next());
                        _tete = &new_interval;
                        }                   
                    }
                else if (bi > _tete->get_bi())
                    {
                    if (bi > _tete->get_bs())
                        {
                        _Inter temp = *_tete->get_next(); // delete later
                        while(&temp != nullptr && bi > temp.get_bs())
                            {
                            temp = *temp.get_next();
                            }
                        if (&temp == nullptr)
                            {
                            _Inter new_interval = _Inter(bi, bs, nullptr);
                            //temp.set_next(new_interval);
                            }
                        else if (bi < temp.get_bi())   // bi < temp.get_bs()
                            {
                            if (bs < temp.get_bi())
                                {
                                _Inter new_interval = _Inter(bi, bs, _tete);
                                _tete = &new_interval;
                                }

                            else if (bs > temp.get_bs())
                                {
                                _Inter new_interval = _Inter(bi, bs, _tete->get_next());
                                _tete = &new_interval;
                                }

                            else if (bs > temp.get_bi())
                                {
                                _Inter new_interval = _Inter(bi, _tete->get_bs(), _tete->get_next());
                                _tete = &new_interval;
                                }                   
                            }
                        else if (bi > temp.get_bi())  // bi < temp.get_bs()
                            {
                            if (bs > temp.get_bs())
                                {
                                _Inter new_interval = _Inter(temp.get_bi(), bs, nullptr);
                                temp = new_interval;
                                }
                            }
                        }
                    }

                }
            }
        void printUinter();
        bool contient(int nb);
        void order();
    };


int main() 
{
    Uinter interval;
    interval.reunion(12, 23);

    return 0;
}

这是错误消息 -

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory '/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2'
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/Cygwin_4.x-Windows/cppapplication_2.exe
make[2]: Entering directory '/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2'
mkdir -p dist/Debug/Cygwin_4.x-Windows
g++ -std=c++11    -o dist/Debug/Cygwin_4.x-Windows/cppapplication_2 build/Debug/Cygwin_4.x-Windows/main.o 
build/Debug/Cygwin_4.x-Windows/main.o: In function `Uinter::reunion(int, int)':
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:56: undefined reference to `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:56:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0x3f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:65: undefined reference to `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:65:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0xa4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:71: undefined reference to `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:71:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0xf7): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:77: undefined reference to `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:77:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0x154): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:99: undefined reference to `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:99:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0x23d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
build/Debug/Cygwin_4.x-Windows/main.o:/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:105: more undefined references to `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)' follow
build/Debug/Cygwin_4.x-Windows/main.o: In function `Uinter::reunion(int, int)':
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:105:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0x28d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:111:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0x2e8): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2/main.cpp:119:(.text$_ZN6Uinter7reunionEii[_ZN6Uinter7reunionEii]+0x349): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Uinter::_Inter::_Inter(int, int, Uinter::_Inter*)'
collect2: error: ld returned 1 exit status
nbproject/Makefile-Debug.mk:62: recipe for target 'dist/Debug/Cygwin_4.x-Windows/cppapplication_2.exe' failed
make[2]: *** [dist/Debug/Cygwin_4.x-Windows/cppapplication_2.exe] Error 1
make[2]: Leaving directory '/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2'
nbproject/Makefile-Debug.mk:59: recipe for target '.build-conf' failed
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory '/cygdrive/c/Users/Iocust/Documents/NetBeansProjects/CppApplication_2'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make: *** [.build-impl] Error 2

很抱歉提供了这样一个不清楚的代码。如果有任何相关性,我使用的是 NetBeans 8.0.2。

您有一个链接器错误。问题出在这里:

public:
    _Inter(int, int, _Inter*);

您没有定义构造函数,而只是声明它,因此链接器会抱怨(它找到声明但找不到定义)。您需要定义,因为没有它,您将无法构造对象 _Inter。如果您没有为构造函数提供任何声明,那么编译器会为您生成一个默认构造函数,但在这种情况下,您提供了一个声明,因此不会再生成默认构造函数。

您需要为 Uinter::_Inter 构造函数提供一个定义,可以内联

public:
    _Inter(int, int, _Inter*){/* definition here */}

或class

之外
Uinter::_Inter(int, int, _Inter*){/* definition here */}

并且您可能想要命名您的构造函数参数

_Inter(int param1, int param2, _Inter* param3)

因为你会需要它们。