简体   繁体   English

C++ 链接时对基类函数的未定义引用(--not-- vtables、构造函数、模板或纯虚函数)

[英]C++ Undefined reference to base class functions at link time (--not-- vtables, constructors, templates, or pure virtual functions)

I'm working on a project attempting to implement a stand-alone base class (A) that can be extended by later classes (such as B and C).我正在开发一个项目,试图实现一个独立的基类 (A),该基类可以由以后的类(例如 B 和 C)扩展。 I want to be able to use them all independently, hence no pure virtual functions, and I want only one copy of each class in any derived classes (hence the virtuals to avoid the Dreaded Diamond).我希望能够独立使用它们,因此没有纯虚函数,并且我只想要任何派生类中的每个类的一个副本(因此使用虚拟来避免 Dreaded Diamond)。 Some classes, like D, need to combine all the previously extended classes, retaining all their functions while implementing additional ones.一些类,如 D,需要组合所有以前扩展的类,在实现附加功能的同时保留它们的所有功能。

For added fun I'm (stuck) using C++03, gcc 4.4.6, and make 3.81.为了增加乐趣,我(卡住了)使用 C++03、gcc 4.4.6 和 make 3.81。

Everything compiles fine, but I keep getting 'undefined reference to '[base class function]' at link whenever and however I attempt to use the base class functions in the derived class.一切都编译得很好,但我总是在链接处收到“对“[基类函数]”的未定义引用,无论何时我尝试在派生类中使用基类函数。

All the answers I've been able to find so far are about incorrectly implementing pure virtual functions, trying to monkey with constructors, or have failed to implement all the members of a class (hence the vtable errors).到目前为止,我能找到的所有答案都是关于不正确地实现纯虚函数、试图与构造函数进行混淆,或者未能实现类的所有成员(因此出现 vtable 错误)。 I'm not (knowingly) doing or intending any of these things.我没有(有意地)做或打算做这些事情。

It would be cool if these were implemented as templates, but it's unfortunately not possible due to the complexity.如果将这些实现为模板会很酷,但不幸的是,由于复杂性,这是不可能的。 I can't post the actual code, but I've mocked up examples resembling the basic structure and behavior:我无法发布实际代码,但我模拟了类似于基本结构和行为的示例:

Header file declaring the classes:声明类的头文件:

#ifndef CODE_H
#define CODE_H

class A
{
protected:
   int a_;
   int b_;
   int c_;

public:

   explicit A() :
      a_(0), b_(0), c_(0) {}

   A(const int X, const int Y, const int Z) :
      a_(X), b_(Y), c_(Z) {}

   A(const A& X) :
      a_(X.A()), b_(X.B()), c_(X.C()) {}

   int doA1(const A& X) const;

   int doA2() const;

   A getA() const;

   A& operator=(const A& X);

   const int& A() const {return a_;}
   const int& B() const {return b_;}
   const int& C() const {return c_;}

   //One for each operator but not shown for brevity
   A operator+(const A& X) const;
   void operator+=(const A& X);
   A operator+(const int X) const;
   void operator+=(const int X);
};

class B : public virtual A
{
protected:
   int d_;

public:

   explicit B() :
      A(), d_(0) {}

   B(const int D, A X) :
      A(X), d_(D) {}

   B(const int D) :
      d_(D) {}

   int doB1(const B& X) const;

   B getB() const;

   B& operator=(const B& X);

   const int& D() const {return d_;}

   //One for each operator but not shown for brevity.
   //int d_ doesn't need to be modified by the operators, so it's ignored in their implementation.
   B operator+(const B& X) const {return B(d_, (A::operator+(X.getA())));}
   void operator+=(const B& X)   {A::operator+=(X.getA());}
   B operator+(const int X) const; {return B(d_, (A::operator+(X)));}
   void operator+=(const int X)    {A::operator+(X);}
};

class C : public virtual A
{
protected:
   int e_;
   int f_;
   int g_;

public:

   explicit C() :
      A(), e_(0), f_(0), g_(0) {}

   C(const int U, const int V, const int W, 
     const int X, const int Y, const int Z) :
         A(U, V, W), e_(X), f_(Y), g_(Z) {}

   C(const A& W, 
     const int X, const int Y, const int Z) :
         A(W), e_(X), f_(Y), g_(Z) {}

   C(const C& X) :
         C(X.A(), X.B(), X.C()), e_(X.E()), f_(X.F()), g_(X.G()) {}

   int doC1(const C& X) const;

   C getC() const;

   C& operator=(const C& X);

   const int& E() const {return e_;}
   const int& F() const {return f_;}
   const int& G() const {return g_;}

   //One for each operator but not shown for brevity
   C operator+(const C& X) const;
   void operator+=(const C& X);
   C operator+(const int X) const;
   void operator+=(const int X);
};

class D : public virtual B, public virtual C
{
public:

   explicit D() :
      B(), C() {}

   D(const int D, C Y) :
      B(D), C(Y) {}

   int doD1(const D& X) const;

   int doD2() const;

   D getD() const;

   D& operator=(const D& X);

   //One for each operator but not shown for brevity.
   D operator+(const D& X) const {return D(d_, (C::operator+(X.getC())));}
   void operator+=(const D& X)   {C::operator+=(X.getC());}
   D operator+(const int X) const; {return D(d_, (C::operator+(X)));}
   void operator+=(const int X)    {C::operator+(X);}
};
#endif

File implementing A:文件实现A:

#include header.h

int A::doA1(const A& X) const
{
   int doStuff;
   //does stuff.
   return doStuff;
}

int A::doA2() const
{
   int doStuff2;
   //does stuff.
   return doStuff2;
}

A A::getA() const
{
   A out(a_, b_, c_);
   return out;
}

A& A::operator=(const A& X)
{
   if (this != &X)
   {
      a_ = X.a_;
      b_ = X.b_;
      c_ = X.c_;
   }
   return *this;
}

//One for each operator but not shown for brevity
A A::operator+(const A& X) const
{
   return A(a_ + X.a_, b_ + X.b_, c_ + X.c_);
}

void A::operator+=(const A& X)
{
   a_ += X.a_;
   b_ += X.b_;
   c_ += X.c_;
}   

 A A::operator+(const int X) const
{
   return A(a_ + X, b_ + X, c_ + X);
}

void A::operator+=(const int X)
{
   a_ += X;
   b_ += X;
   c_ += X;
}   

File implementing B:文件实现 B:

#include header.h

int B::doB1(const B& X) const
{
   //Linker complains on both doA1 and getA, even if I qualify them or remove all the qualifiers
   return (A::doA1(X.getA()));
}

B B::getB() const
{
   //Also complains here, with or without qualifiers.
   B out(d_, A::getA());
   return out;
}

B& B::operator=(const B& X)
{
   if (this != &X)
   {
      //Also here, for presumably the same reason.
      A::operator=(D.getA());
      d_ = X.d_;
   }
   return *this;
}

I can provide mockups for C and D as well, though they follow the same basic pattern as A and B.我也可以为 C 和 D 提供模型,尽管它们遵循与 A 和 B 相同的基本模式。

Based on the answers I've seen so far I should, at most, only need to add the base class qualifier to the functions to avoid any accidental name hiding, but that doesn't appear to work.根据我目前看到的答案,我最多只需要将基类限定符添加到函数中,以避免任何意外的名称隐藏,但这似乎不起作用。 Also strangely: instantiated objects can't seem to find their public functions (like in doB1).同样奇怪的是:实例化的对象似乎无法找到它们的公共函数(如在 doB1 中)。 Am I just a moron missing something obvious (which I wouldn't be surprised coming from a C background)?我只是一个白痴,遗漏了一些明显的东西(来自 C 背景我不会感到惊讶)?

You are defining global functions instead of class methods.您正在定义全局函数而不是类方法。

In class Aclass A

int doA1(const A& X) const;
int doA2() const;

Implemetation实施

int A::doA1(const A& X) const
int doA2() const

Thera is no A:: in second case.在第二种情况下,Thera 不是A::

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果 C++ 接口(抽象 class 只有纯虚函数)删除复制/移动赋值构造函数 - Should a C++ interface (abstract class with just pure virtual functions) delete the copy/move assignment constructors beginner c ++:基类中的虚函数 - beginner c++: virtual functions in a base class 如果使用vtable实现具有虚函数的类,那么如何实现没有虚函数的类? - If classes with virtual functions are implemented with vtables, how is a class with no virtual functions implemented? C ++纯虚函数使类大小变大 - C++ Pure Virtual Functions Make Class Size Larger C ++使用纯虚函数实例化抽象类的子级 - C++ Instantiating childs of an abstract class with pure virtual functions 包含纯虚函数的模板类的C ++实现 - C++ implementation of template class with pure virtual functions in it 派生类销毁期间纯虚函数的范围 - 在C ++中 - Scope of pure virtual functions during derived class destruction - In C++ 没有纯虚函数的C++抽象类? - C++ abstract class without pure virtual functions? 派生类中的C++纯虚函数实现 - C++ pure virtual functions implementation in derived class 仅具有纯虚函数的类中的构造函数会导致派生类中的错误 - Constructors in class with only pure virtual functions causes errors in derived classes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM