-2

So this is part of a bigger project. I have 3 different files. The first one is a class from a previous project that is just being used as a type (visitor.h) so I won't include it as I know it works. Then I have written an abstract class and another abstract class which inherits from the first one in space.h like so:

class space{

public:
    virtual int get_vis_count() const = 0;
    virtual int __enter(Visitor *v) = 0;
    virtual int search(Visitor *v) = 0;
    virtual Visitor* __exit(int index) = 0;
    virtual void print() const = 0;
    virtual ~space() { };

};

class capped_space: public space{

    public:
    virtual int get_capacity() const = 0;
    virtual int has_space() const = 0;
};

Now in my classes.h i have several classes and the error:

classes.o: In function `office::office(building*, int, int)':
classes.cpp:(.text+0x8fe): undefined reference to `vtable for office'
classes.o: In function `office::~office()':
 classes.cpp:(.text+0xe1a): undefined reference to `vtable for  office'

pops. classes.h:

class office:public capped_space{

private:
int office_number, No;
int  current_visitors;
int _f;
vector<Visitor*> visitors;

public:
office(building *b, int on, int m);
int get_capacity() const;
int has_space() const;
int get_vis_count() const;
int get_numb() const;
int __enter(Visitor * visitor);
int search(Visitor *v);
Visitor* __exit(int index);
Visitor* done();
void print() const;
~office();
};

classes.cpp:

office::office(building *b, int on, int m): office_number(on),  current_visitors(0), _f(m){
  No = b->get_space_size('o');
  cout << "Office number: " << office_number << "\thas been created\n";
}

int office::get_vis_count() const{
  return current_visitors;
}

int office::has_space() const{
  return (current_visitors < No);
}

int office::get_numb() const{
  return office_number;
}

int office::__enter(Visitor * visitor){
  if(visitor == NULL) return -1;
  if(has_space()){
    if(!visitor->__done()){
        if((visitor->get_office() == office_number)){
            visitors.push_back(visitor);
            cout << "Entering office " << _f << "-" << office_number << "\t: ";
            visitors[current_visitors]->print_v();
            current_visitors++;
            return 1;
        }else{
            return 0;
        }
    }else{
        return 1;
    }
}else{
    cout << "Please, wait outside for entrance in office number: " <<   office_number << endl;
    return 0;
  }
}

Visitor* office::__exit(int index){
  if (visitors[index]->__done()){
    Visitor *nav;
    nav = visitors[index];
    visitors.erase(visitors.begin() + index);
    current_visitors--;
    return nav;
  }else{
    return NULL;
  }
}

Visitor* office::done(){
  if(current_visitors){
    int random;
    random = rand() % current_visitors;
    visitors[random]->__set_done();
    cout << "Exiting office " << _f << "-" << office_number << "\t: ";
    visitors[random]->print_v();
    return __exit(random);
  }else{
    return NULL;
  }
}

void office::print() const{
    if(current_visitors != 0){
      cout << "Floor: " << _f << endl;
      cout << "Office: " << office_number << endl;
      for (int i = 0; i < No; i++)
      {
        visitors[i]->print_v();
      }
      cout << endl;
}
} 

office::~office(){
    cout << "End of the work!\n";
 }

The second error pops in class floor's functions but I hope that if I figure out the office error I will also figure out floor's.

If any more code is needed please comment and I will edit.

P.S. please ignore some ifs I may have left behind. The code was originally handling arrays of pointers and now I am trying to make it handle vectors of pointers so there may be some leftover checks

  • **Minimal**, Complete and verifiable example, please. There could be several reasons for this behavior, only MCVE can pinpoint to a specific one. – SergeyA Dec 26 '18 at 17:31
  • 1
    Off-topic: Identifiers with a double underscore anywhere in them are reserved to the implementation for any use. You are risking nasal demons with `__enter` and `__exit`. – StoryTeller - Unslander Monica Dec 26 '18 at 17:33
  • Didn't know about that. I just used it because I tried writing exit and it glowed. Later I found out it is an existing function. I am fairly new at programming. Thanks for the tip – Jordan Sapida Dec 26 '18 at 19:42
  • If you look at the disassembly, do you see symbols called "vtable for blah" being defined? – curiousguy Jan 07 '19 at 15:34

1 Answers1

0

You are missing definitions for some of the virtual methods that you've declared in office, namely search and get_capacity.

As a result, the compiler can't generate a virtual function table for office class because it doesn't have addresses for these virtual functions to put there. Hence a "very useful" error message, because, from compiler's perspective, the problem is that virtual table is missing and not why it's missing.

r3mus n0x
  • 5,954
  • 1
  • 13
  • 34
  • Oh. I understand what you are saying but do you maybe know the reason this error poped on the constructor? Is it the "default" thing to do? – Jordan Sapida Dec 26 '18 at 19:44
  • @JordanSapida, I don't have any specific source of information about this, just common sense, but it's probably because the virtual table pointer (which is typically a "hidden" member of the object) is initialized in the constructor (or, more accurately, a compiler-generated part of the constructor), but there is no virtual table to point to, hence the unresolved reference. – r3mus n0x Dec 26 '18 at 19:54
  • Thank you. Really helpful feedback. – Jordan Sapida Dec 26 '18 at 19:56
  • That isn't completely correct. The compiler will generate a vtable with symbols of virtual functions, not the corresponding values; only during linking the symbols are resolved. Missing symbols for virtual function addresses will cause a link error obviously, but not because of a missing vtable: the error will be because of a non-missing vtable that refers to these symbols, and because the vtable is used because the constructor and destructor are used; if the class was never instantiated, you would probably be able to link without the virtual functions. – curiousguy Jan 06 '19 at 18:07
  • @curiousguy, this makes sense but why then the error says `undefined reference to 'vtable for office'` and not undefined reference to the missing function? – r3mus n0x Jan 07 '19 at 10:30
  • @r3musn0x Probably because that vtable wasn't even generated in any TU (translation unit) because **one particular** (I don't know which but it's usually documented by the implementation) virtual function definition was not present on any TU. That's a trigger for the generation of the vtable symbol. If you look at the disassembly, you can see that the vtable references plenty of other symbols, not limited to regular virtual function code: also virtual thunks (for calls via another base class) and the `typeinfo` of the class. – curiousguy Jan 07 '19 at 15:38
  • @curiousguy, I'm confused, in your previous comment you said that there is a "non-missing vtable that refers to these [missing] symbols", but now you're saying that it "wasn't even generated", so which one is it? – r3mus n0x Jan 07 '19 at 16:02
  • @r3musn0x 1) The fact that many virtual function definitions are missing cannot in itself prevent the generation of the vtable that refers to these symbols; but if the vtable symbol is used, then these virtual function symbols will be needed to complete the linking, just as a function F that call another function G that doesn't have a definition, as long as F isn't used. In fact you can simulate a vtable in C/C++ with a struct (not an array!) of function pointers of the appropriate types, with that same effect. – curiousguy Jan 07 '19 at 18:07
  • 2) In this case, the error message **undefined reference to `vtable for office'** indicates that vtable symbol was not generated in any TU. That cannot be caused by the fact that the vtable refers to other symbols. But the compiler never emitted the vtable because the definition of one designated virtual function was not found, and the vtable is only produced when **that virtual function** is defined. It's a convention. – curiousguy Jan 07 '19 at 19:11