0

I would like to learn how to define a derived class constructor in one file so that I could implement it in another file.

public:
Derived(std::string name) : Base(name);
~Derived();

Destructor works as expected, however with constructor I either add {} at the end (instead of a semicolon) and then get redefinition of 'Derived' error or I get asked to add {} instead of a semicolon. What is a way to separate definition and implementation in this case?

kuk
  • 127
  • 1
  • 8
  • 4
    The `: Base (name)` bit is part of the definition. If you just want a declaration, that would be `Derived(std::string name);`. – Nathan Pierson Dec 06 '21 at 17:00
  • I think you meant, "separate _declaration_ and _definition_". For the rest of us "definition" and "implementation" are the same thing, and it's "declaration" that represents the implementation-less thing you inappropriately called "definition". – Wyck Dec 06 '21 at 17:06

3 Answers3

1

Base.h

#include <string>

class Base
{
protected:
    std::string name;
    ...
public:
    Base(std::string name);
    virtual ~Derived();
    ...
};

Base.cpp

#include "Base.h"

Base::Base(std::string name)
    : name(name)
{
    ...
}

Base::~Base()
{
    ...
}

Derived.h

#include "Base.h"

class Derived : public Base {
    ...
public:
    Derived(std::string name);
    ~Derived();
    ...
};

Derived.cpp

#include "Derived.h"

Derived::Derived(std::string name)
    : Base(name)
{
    ...
}

Derived::~Derived()
{
    ...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • What is the benefit of base destructor being virtual? – kuk Dec 06 '21 at 17:21
  • 3
    @VytautasK [See here](https://stackoverflow.com/questions/461203/when-to-use-virtual-destructors). It's so that if you delete a `Derived` object by calling `delete foo;` where `foo` is a `Base*` pointer whose pointed-to object is a `Derived` instance, everything works correctly. – Nathan Pierson Dec 06 '21 at 17:32
1

You can separate declaration and definition like so:

class Derived : public Base {
public:
   Derived(std::string name); // declaration
   // ... other members here
};

Then, elsewhere:

// definition
Derived::Derived(std::string name) : Base(name) {
  // ...
}
Wyck
  • 10,311
  • 6
  • 39
  • 60
1

You do it the same way as for any other member function of the class. For example,

base.h

#pragma once 

#include <string>

class Base 
{
    std::string name;
    public:
        Base() = default;
        Base(std::string pname);//declaration
        //other members
};

base.cpp

#include "base.h"
#include <iostream>
//definition
Base::Base(std::string pname): name(pname)
{
    std::cout<<"Base constructor ran"<<std::endl;
    
}

derived.h

#pragma once
#include "base.h"
class Derived : public Base
{
  public: 
    Derived(std::string pname);//declaration
};

derived.cpp

#include "derived.h"
#include <iostream>
//definition
Derived::Derived(std::string pname): Base(pname)
{
    std::cout<<"Derived constructor ran"<<std::endl;
}

main.cpp


#include <iostream>
#include "derived.h"
#include "base.h"

int main()
{
    
    Derived d("anoop");
    return 0;
}

Jason
  • 36,170
  • 5
  • 26
  • 60