0

I have the following code:

class Father
{
public:
    virtual void sleep() = 0;
protected:
    Father();
    ~Father();
}

// Both sleep() and Son(int, int, int) are implemented in son.cpp
class Son : Father
{
    Son(int a, int b, int c);
    void sleep() override;
}

In main:

Son son(1, 2, 3);

When I try to compile, I get this error:

In sketch\src\son.cpp.o undefined reference to `Father::Father()'

The same error also for the destructor.

What is happening here? I never mentioned or included Father in the son.cpp.

I tried to remove the declaration of the constructor and destructor from the father, then it worked.

UPDATE:

My goal here is to prevent instantiating the abstract Father. So I don't want to remove the declaration of the constructor.

Mohammed Noureldin
  • 14,913
  • 17
  • 70
  • 99
  • Here you've *declared* constructor and destructor for `Father`, but you haven't *defined* them. If you remove the declarations, the compiler just provides default ones for you. – Fred Larson Nov 17 '20 at 21:20
  • It's the linking stage that fails to find the `Father` special member functions. When you omit their declarations from `Father`'s definition, the compiler generates defaults for you. Also note that `Father`'s destructor should be either `protected` or `virtual` in order to prevent UB when deleting an instance of static `Father` type. – lubgr Nov 17 '20 at 21:21
  • It's pretty obvious that you're missing these function definitions. The easiest fix would be to omit the declarations of `Father::Father()` and `Father::~Father()` completely, and let the compiler generate them (though mind @lubgr comment regarding the `virtual` destructor). – πάντα ῥεῖ Nov 17 '20 at 21:22
  • @πάνταῥεῖ I want to make the constructor of the `Father` protected. Therefore I cannot remove the declerations. – Mohammed Noureldin Nov 17 '20 at 21:25
  • 2
    @MohammedNoureldin Then just tell it `Father() = default;` and something like `virtual ~Father() = {}` for the destructor. – πάντα ῥεῖ Nov 17 '20 at 21:26
  • 1
    If you have one or more virtual functions, the class *is* abstract. You don't need to worry about making constructors protected. You may want to have a protected destructor, though, to prevent polymorphic deletion. Or you could make the destructor `virtual` to permit polymorphic deletion. – Fred Larson Nov 17 '20 at 21:29
  • 2
    If you don't want `Father` to be instantiated, don't declare any constructor, make the destructor `virtual` and `= default;`, and you are good to go. The destructor must still be there and `virtual`, because even if you prevent `Father` to be instantiated, child class instances can be deleted through `Father`. – lubgr Nov 17 '20 at 21:30
  • Thank you all for your help! Please any or all of you add these comments as answers, unfortunately, I will be able to accept only one ^^", nevertheless, thank you all! – Mohammed Noureldin Nov 17 '20 at 21:36
  • @MohammedNoureldin _"Please any or all of you add these comments as answers"_ The linked duplicate already contains all the answers needed. It's just as the linker error says: You're missing the definition of these functions. There are several ways to define functions declared in class definitons, constructors and destructors are no exception, besides the compiler can generate default versions for these, which the linkker will find as well as manually defined implementations. – πάντα ῥεῖ Nov 17 '20 at 21:44

0 Answers0