0

It is probably a sily mistake... I started to code using C++ language. I have created an abstract class:

class Animal{
    protected:
        string name;
        int age;
        string noise;
        string scientific_name;

    public:

        Animal(){

            cout<<"teste"<<endl;
        }

        virtual void setScientificName();

        string getName(){
          return name;
        }



        int getAge(){
            return this->age;
        }
        //virtual int getAge();


        string getScientificName(){
            return scientific_name;
        };

};

Derivated it into to other classes:

class Dog: public Animal{




    public:

        Dog():Animal(){
            setScientificName();
        }

        void setScientificName() override {
            scientific_name = "Canis Lupus Familiaris";
        }
};

class Cat: public Animal{


    public:
        Cat():Animal(){
            setScientificName();
        }

        void setScientificName() override {
            scientific_name = "Felis catus";
        }
};

Tested it:

int main()
{
    Cat c;

    cout << "Hello world! " << c.getScientificName() << endl;
    system("Pause");
    return 0;
}

Even though I have implemented the virtual function, I´ve got the error:

||=== Build: Debug in teste (compiler: GNU GCC Compiler) ===| obj\Debug\main.o||In function ZN6AnimalC2Ev':| C:\Users\study\Código em C\teste\main.cpp|15|undefined reference to vtable for Animal'| obj\Debug\main.o||In function ZN6AnimalD2Ev':| C:\Users\study\Código em C\teste\main.cpp|6|undefined reference to vtable for Animal'| ||error: ld returned 1 exit status| ||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 2 second(s)) ===|

Why?

user207421
  • 305,947
  • 44
  • 307
  • 483
Pedro
  • 81
  • 2
  • 8
  • 6
    You didn't implement it *in `Animal`,* and that is what the linker error is saying. If you don't want to do that, make it pure virtual: `virtual void setScientificName() = 0;` And in general a class with virtual methods should have a virtual destructor. – user207421 Jun 05 '22 at 07:27
  • 1
    This is also just a kind of weird method to make virtual. It's weird to have a `setFoo` method that doesn't take any arguments. It's weird for `Animal` to have a `scientific_name` data member and accessor but not a setter for it. It's weird that even if your code compiled, `c.getScientificName()` would still be `""` and not `"Felis catus"` because you never called `c.setScientificName()`. – Nathan Pierson Jun 05 '22 at 07:38
  • 1
    just learning to use C++... – Pedro Jun 05 '22 at 14:52
  • *"I have created an abstract class:"* -- no, you did not. An [abstract class](https://en.cppreference.com/w/cpp/language/abstract_class) is one with a pure virtual function. Your class has a virtual function, but not a pure virtual function. So... I guess the point that needs clarification is whether the class is as intended and you just misused terminology when describing it, or whether the terminology describes your goal and you messed up the class definition. – JaMiT Jun 05 '22 at 18:12

0 Answers0