MMT
MMT

Reputation: 27

Multiple definition with 2 header files

I am using CodeBlocks.

In C++, I have 3 header files and 3 cpp files like below.

Base.h

class Base
{
public:
    virtual int funky(int x, int y);
};

Base.cpp

 int funky(int x, int y) {
  return x+y;
}

FirstClass.h

class FirstClass: public Base
{
public:
    virtual int funky(int x, int y);
};

FirstClass.cpp

int funky(int x, int y) {
  return x+y;
}

SecondClass.h

class SecondClass: public Base
{
public:
    virtual int funky(int x, int y);
};

SecondClass.cpp

int funky(int x, int y) {
  return x+y;
}

In this condition I take error of "multiple definition." But, I have to use these functions with the same names. I tried

int funky (int x, int y) override;
 

but it did not work.

I need all three function, because when I want to call them like below and if they are defined like above, I cannot reach them.

 vector<Base> BASE =  {FirstClass(), SecondClass()};
 BASE[1]->funky(1,2)

Do you have any suggestion? I am open to another approach to this problem. Thank you.

Upvotes: 0

Views: 403

Answers (2)

Ted Lyngmo
Ted Lyngmo

Reputation: 118017

int funky(int x, int y) in both your .cpp files are defined as free functions that has nothing to do with the classes you've defined. They have the same signature and you therefore get a linking problem with multiple definitions.

I suggest you make the destructor in the base class virtual, just in case you want to destroy objects through a base class pointer.

Inheriting, overriding and defining the member functions could look like this:

class Base {
public:
    virtual ~Base() = default;           // virtual destructor
    virtual int funky(int x, int y) = 0; // = 0 added to make it pure virtual
};
class FirstClass : public Base {         // inherit
public:
    int funky(int x, int y) override;    // now you can override
};
int FirstClass::funky(int x, int y) {    // class member function definition
    return x+y;
}

And you need to do the same for SecondClass.

You should not use vector<Base> though. You will not store Base objects but most probably pointers to objects of types derived from Base, like FirstClass and SecondClass. I suggest using the smart pointer std::unique_ptr for this:

#include <memory>

int main() {
    std::vector<std::unique_ptr<Base>> BASE;

    BASE.emplace_back(std::make_unique<FirstClass>());
    BASE.emplace_back(std::make_unique<SecondClass>());
    
    std::cout << BASE[0]->funky(2,3) << '\n';
    std::cout << BASE[1]->funky(2,3) << '\n';
}

Demo

Upvotes: 2

HARSH MITTAL
HARSH MITTAL

Reputation: 760

In the above code sample, you defining funky in two different cpp files but have declared in your class. So following should be the correct format:

FirstClass.cpp

int FirstClass::funky(int x, int y) {
  return x+y;
}

SecondClass.cpp

int SecondClass::funky(int x, int y) {
  return x+y;
}

main.cpp

FirstClass a;
SecondClass b;

cout<<a.funky(1,2)<<" "<<b.funky(3,4)<<endl;

Upvotes: 2

Related Questions