0

Hi Stack Over Flow Users!

Need some help with a pure virtual function. I have googled the error that I get: "undefined reference to 'vtable for Sphere'" and read other posts here at stack overflow. What I gather is that the linker doesn't know where the body of the function is...

Complete error message: /tmp/ccXEIJAQ.o:main.cpp(.rdata$.refptr._ZTV6Sphere[.refptr._ZTV6Sphere]+0x0):undefined reference to 'vtable for Sphere' collect2: error: ld returned 1 exit status

Before pasting relevant code sections below:

Compiling in Cygwin 64 bit environment under Windows 7 Professional.

Abstract Base Class: Primitive Child Class: Sphere

Below is from file Primitive.h

#include "Color.h"
#include "Vector3D.h"

#ifndef PRIMITIVE_H
#define PRIMITIVE_H

class Primitive
{
public:
    Primitive();
    virtual ~Primitive();
    virtual bool intersection(double &, const Vector3D &) = 0;    // pure virutal function

// other functions and private variables omitted for clarity.

};

#include "Primitive.cpp"

#endif

Below is from Sphere.h

#include "Primitive.h"
#include "Point3D.h"
#include <iostream>
#include "Vector3D.h"

using namespace std; 

#ifndef SPHERE_H
#define SPHERE_H

class Sphere : public Primitive
{
public:
    Sphere(const Point3D &, double, const Color &, double, const Color &, double, double);
    Sphere(const Point3D &, double, const Color &, double, const Color &, double, double, const Color &, double, double);
    bool intersection(double &, const Vector3D &);
    Point3D getCenter();
    double getRadius();
    ~Sphere();

    friend ostream & operator << (ostream &, const Sphere &);

protected:
    Point3D *center;
    double radius;
};

#include "Sphere.cpp"

#endif

Below is from Sphere.cpp (Parts not necessary omitted for clarity...)

#include <iostream>
#include "Point3D.h"
#include "Primitive.h"
#include "Sphere.h"
#include "Color.h"
#include "Vector3D.h"

using namespace std;

bool intersection(double &intersect, const Vector3D &ray)
{
    //just trying to get it to compile.

    cout << "Hello.\n";
    return true;
}

I have overwritten the pure virtual function. I have even tried compiling by adding the "virtual" keyword in the declaration of Sphere.h but I get the same error.

There are NO instances of sphere objects in the code yet. When I include Sphere.h and try to compile I get the above error. When I comment out the include of Sphere.h the program compiles.

Any help is greatly appreciated. I will keep searching google to see if I come across a solution.

Post Self
  • 1,471
  • 2
  • 14
  • 34
Yousaf
  • 33
  • 6
  • What the hell is `#include "Primitive.cpp"` ??? – SergeyA Aug 17 '17 at 20:30
  • @RichardCritten, no, wrong duplicate – SergeyA Aug 17 '17 at 20:30
  • @SergeyA: Primitive.cpp contains the definitions of the other methods that were defined in the base class that need bodies. for instance Color Primitive::getDiffuseColor() { return difColor; } – Yousaf Aug 17 '17 at 20:32
  • @Borgleader: For some reason if I do not include the .cpp file in the .h file in the cygwin environment the program will not compile. if I am using XCode I have to take that line out. – Yousaf Aug 17 '17 at 20:34
  • 3
    You should not have to include a cpp file. All that is necessary to compile files that use the class is to include the header. Maybe you are missing something in your header file. The cpp file should not be included; it should just be compiled and linked like any other source code file. – Basya Aug 17 '17 at 20:36
  • @Yousaf I dont use Cygwin but I find that very suspicious. I suspect you forgot to either tell cygwin to compile your file or to link it. You really should not have to include it in a header like that. – Borgleader Aug 17 '17 at 20:38
  • @Basya Perlman & Borgleader. It's probably related to my unfamiliarity using cygwin or g++ / gcc and linking files. Write now I just run g++ fileName.cpp and with the includes as written everything automatically compiles and gets linked. Its probably incorrect and I'll have to look into making a proper makefile. – Yousaf Aug 17 '17 at 20:46

2 Answers2

3

The problem is, that in Sphere.cpp you are defining another function named intersection. What you need to do is implement the function declared in the class like so:

bool Sphere::intersection(double &intersect, const Vector3D &ray)

instead of

bool intersection(double &intersect, const Vector3D &ray)
Post Self
  • 1,471
  • 2
  • 14
  • 34
2

You forgot to include the class name in the function definition:

bool Sphere::intersection(double &intersect, const Vector3D &ray)
{
    //just trying to get it to compile.

    cout << "Hello.\n";
    return true;
}
Robinson
  • 9,666
  • 16
  • 71
  • 115