C++ 未定义对析构函数的引用和对返回的局部变量的引用

C++ Undefined reference to destructor and reference to local variable returned

提问人:Iocust 提问时间:11/27/2015 更新时间:11/27/2015 访问量:1403

问:

我正在尝试创建一个继承自另一个类模板的类模板,第一个是只包含纯虚拟方法的类,第二个是将作的类。我尝试构建的是一个向量类,其大小由第二个模板参数决定。基类将用于创建另一个向量类,其大小对于类的每个对象都不同。

摆弄了 2-3 天后,我不知道如何修复尝试编译项目时发生的一系列错误。

这是标题 (Vect.hpp)

#ifndef NEWFILE1_HPP
#define NEWFILE1_HPP

#include <cstddef>    
#include <iostream>    
#include <exception>
#include <stdexcept>   

template <class elem>
class Vect
{
    public:          
        virtual elem& operator[] (std::ptrdiff_t nIndex) =0;
        virtual const elem& operator[] (std::ptrdiff_t nIndex) const =0;
        virtual Vect& operator+() =0;
        virtual Vect& operator-() =0;
        virtual Vect& operator+(const elem&) =0;
        virtual Vect& operator-(const elem&) =0;
        //virtual Vect& operator*(const elem&) =0;

        virtual ~Vect();

};


template <class elem, std::size_t taille=10>

class Vect_fixe: public Vect<elem>
{
    template <typename T, std::size_t D>
        friend std::ostream& operator<< (std::ostream&, const Vect_fixe<T, D>&);

    public:
    Vect_fixe():vecteur(new elem[taille]) {};
    virtual elem& operator[] (std::ptrdiff_t nIndex);
    virtual const elem& operator[] (std::ptrdiff_t nIndex) const;
    virtual Vect_fixe& operator+();
    virtual Vect_fixe& operator-();
    virtual Vect_fixe& operator+(const elem&);
    virtual Vect_fixe& operator-(const elem&);


    private:
    elem vecteur[taille];
    ~Vect_fixe(){delete[] vecteur;}
};

这是定义函数和执行测试的那个(main.cpp)

#include <cstdlib>
#include "Vect.hpp"
#include <exception>
#include <stdexcept>   

template <class elem, std::size_t taille>
elem& Vect_fixe<elem, taille>::operator[] (std::ptrdiff_t nIndex)
{
    if (nIndex >= taille)
        throw std::out_of_range("Index out of range.");
    return vecteur[nIndex];

};

template <class elem, std::size_t taille>
const elem& Vect_fixe<elem, taille>::operator[] (std::ptrdiff_t nIndex) const
{
    if (nIndex >= taille)
        throw std::out_of_range("Index out of range.");
    return vecteur[nIndex];

};

template <class elem, std::size_t taille>
Vect_fixe<elem, taille>& Vect_fixe<elem, taille>::operator +()
{
    return *this;
}

template <class elem, std::size_t taille>
Vect_fixe<elem, taille>& Vect_fixe<elem, taille>::operator -()
{
    Vect_fixe<elem, taille> temp_v;
    for (int i=0; i<taille; i++)
        temp_v[i] = -temp_v[i];
    return temp_v;
}

template <class elem, std::size_t taille>
Vect_fixe<elem,taille>& Vect_fixe<elem, taille>::operator+(const elem&)
{
    Vect_fixe<elem, taille> temp_v;
    elem obj;
    for (int i=0; i<taille; i++)
        temp_v[i] += obj;
    return temp_v;
}

template <class elem, std::size_t taille>
Vect_fixe<elem,taille>& Vect_fixe<elem, taille>::operator-(const elem&)
{
    Vect_fixe<elem, taille> temp_v;
    elem obj;
    for (int i=0; i<taille; i++)
        temp_v[i] -= obj;
    return temp_v;
}


int main() {

    int x;
    x = 5;
    Vect_fixe<int, 10> vect;
    //std::cout<< vect << std::endl;



    return 0;
}

我得到的错误如下:

g++ -std=c++14    -o dist/Debug/Cygwin_4.x-Windows/cppapplication_2 build/Debug/Cygwin_4.x-Windows/Vect.o build/Debug/Cygwin_4.x-Windows/main.o 
build/Debug/Cygwin_4.x-Windows/main.o: In function `Vect_fixe<int, 10ul>::~Vect_fixe()':
/cygdrive/e/University/BA2/Langages de Programmation/Projet C++/CppApplication_2/Vect.hpp:48: undefined reference to `Vect<int>::~Vect()'
/cygdrive/e/University/BA2/Langages de Programmation/Projet C++/CppApplication_2/Vect.hpp:48:(.text$_ZN9Vect_fixeIiLm10EED1Ev[_ZN9Vect_fixeIiLm10EED1Ev]+0x3f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Vect<int>::~Vect()'
collect2: error: ld returned 1 exit status

导致这种状态的原因是我试图修复以前的错误,即返回对局部变量的引用。我在某些函数中放置了 const 关键字,但这似乎并没有解决问题,所以我恢复了,这就是发生的事情。我真的不清楚这个错误,可能是因为我习惯于用 Python 编程,几乎每个错误都会得到解释。

C++ 模板 继承编译 器错误未 定义引用

评论

0赞 juanchopanza 11/27/2015
您应该坚持每个帖子一个问题。
0赞 Iocust 11/27/2015
@juanchopanza 从技术上讲,只有一个问题,我只是给出了它发生的背景。但是,是的,也许我选择的标题不是最好的。
0赞 Jean-Baptiste Yunès 11/27/2015
您的错误不是编译器错误,而是链接器错误。你基本上使 ,这是无意义的。缺少一个可执行文件名称,在这里您将 main.o 链接到 Vect.o。链接命令应如下所示。如果是 Makefile 生成的链,请检查;如果是 IDE,则必须仔细检查构建链。g++ -std=c++14 -o Vect.o main.og++ -o myApp Vect.o main.o
1赞 Neil Kirk 11/27/2015
您的 Vect 析构函数需要在某个地方有一个身体。
2赞 juanchopanza 11/27/2015
从技术上讲,这里没有问题。但你似乎在问两个截然不同的问题。

答:

4赞 Bathsheba 11/27/2015 #1
  1. 你的一些函数(例如)正在返回对堆栈分配变量的引用。一旦函数退出,这些将超出范围。operator -()

这是未定义的行为

补救措施是返回值副本。从函数中删除引用返回类型。

  1. 您需要为 和 提供实现。如果不需要它们,则不要在类中声明它们。~Vect()~Vect_fixe()

评论

0赞 Iocust 11/27/2015
感谢您的快速答复!我想通过引用返回类型,您的意思是我返回了我创建的临时变量?我理解,但在这种情况下,您会建议直接修改对象吗?我没有看到返回修改版本的另一种方法。
0赞 Bathsheba 11/27/2015
实际上,您不能通过引用返回临时变量。如果可以返回修改后的内容,则作为引用返回即可。this*this
2赞 Guillaume Racicot 11/27/2015 #2

您忘记实现析构函数,您应该在 cpp 文件中实现析构函数。这将删除对析构函数的未定义引用。VectVect_fixe

如果将 from 的返回类型更改为 ,则应修复错误。不能返回对局部变量的引用。这是未定义的行为。reference to a local variableoperator-Vect&Vect

评论

0赞 Iocust 11/27/2015
哦,我以为纯粹的虚拟析构函数不需要那个。我的错,我对继承还很陌生。非常感谢:)
0赞 Guillaume Racicot 11/27/2015
是的,除非你隔离,否则他们需要virtual ~Vect() = default
0赞 Guillaume Racicot 11/27/2015
Vector 是一个相当奇怪的类,使用继承,但它仍然是一个很好的做法。
0赞 Iocust 11/27/2015
希望有一天能派上用场~