-1

Sorry for the noob question..

devf.h

#ifndef DEVF_H
#define DEVF_H

#include <string>

struct A {
    int ax();
    std::string ay(std::string jj);
};

struct B {
    struct A* f;            

    int bx() {
        return f->ax();
    }

    std::string by(std::string jj){
        return f->ay(jj);
    }        
};

#endif // DEVF_H

devf.cpp

#include "devf.h"

int A::ax() {
    return 5;
}

std::string A::ay(std::string jj){
    return jj;
}

I get this error:

multiple definition of `A::ax()'

multiple definition of `A::ay(std::string)'

How can I solve this problem? I want the definitions of ax and ay functions in header file and the implementions in .cpp

LeAdErQ
  • 45
  • 10

1 Answers1

1

Try doing this with your code:

devf.h

#ifndef DEVF_H  // Add this line
#define DEVF_H  // Add this line

// #include <iostream> // removed this as not needed from what is shown
#include <string> // added this as is needed

struct A {    
    int ax() const; // added const as it doesn't change
    std::string ay( const std::string& jj ) const; // changed string to const ref & added const  
};

struct B {
    /*struct*/ A* f; // keyword struct not needed here.

    int bx() const { // added const
        return f->ax();
    }

    std::string by( const std::string& jj ) const { // changed to const ref & added const
        return f->ay( jj );
    }        
};

#endif // !DEVF_H  // Add this line

devf.cpp

#include "devf.h"

int A::ax() const {
    return 5;
}

std::string A::ay( const std::string& jj ) const {
    return jj;
}

Then you asked this or made this statement:

How can I solve this problem? I want the definitions of ax and ay functions in header file and the implementions in .cpp


devf.h

#ifndef DEVF_H 
#define DEVF_H

#include <string>

struct A {    
    int ax() const;
    std::string ay( const std::string& jj ) const;    
};

struct B {
   A* f;

   int bx() const;     
   std::string by( const std::string& jj ) const; 
};

#endif // !DEVF_H

devf.cpp

#include "devf.h"

int A::ax() const {
    return 5;
}

std::string A::ay( const std::string& jj ) const {
    return jj;
}

int B::bx() const {
    return f->ax();
}

std::string B::by( const std::string& ) const { 
    return f->ay( jj );
}        

This should help from what you have shown.


I've tried it with this:

main.cpp

#include <iostream>
#include "devf.h"

int main() {

    B b;
    std::cout << b.bx() << std::endl;
    std::cout << b.by( "hello world" ) << std::endl;

    std::cout << "\nPress any key and enter to quit." << std::endl;
    char q;
    std::cin >> q;
    return 0;
}

output

5
hello world

Press any key and enter to quit.


- EDIT

I asked the OP: Are you including other header files?

The OP answered with:

Yes, the header "devf.h" is included in other headers

And I believe this is where the OP's problem resides. I believe that the OP is a victim of Circular Includes which will result in multiple definitions.


Example:

A.h

#ifndef A_H
#define A_H

#include "B.h" // circular include

struct A {
    int a;
    B b;
};

#endif  // !A_H

B.h

 #ifndef B_H
 #define B_H

 #include "A.h" // circular include

 struct B {
     int b;
 };

 #endif // !B_H

To resolve this circular include problem...

  • You need to use class or struct prototypes - forward declarations in the headers; works with pointer & reference types.
  • Only include other header files within a header file if the definition not the declaration is needed.
  • Once you have the class or struct's forward declaration in the header file remove that class's include directive and put it within its cpp file

fixing the above example:

A.h

#ifndef A_H
#define A_H

// Since A has a pointer to B we remove the include from here
// and replace it with a forward declaration or class prototype...
// #include "b.h" // cicular include
class B;
struct A {
    int a;
    B b;
};

#endif // !A_H

A.cpp

#include "A.h"
#include "B.h" // moved the include to here - prevents circular includes

B.h

 #ifndef B_H
 #define B_H

 // Since B does not require A we can omit this all together.
 //#include "A.h" // circular include

 struct B {
     int b;
 };

 #endif // !B_H

B.cpp

#include "B.h"

You can refer to this Q & A Resolve build errors due to circular dependency amongst classes on stack for a more detailed explanation.


Once you go through the rest of your code base and fix all of the circular includes you should have no error as the above set of classes do compile and run without error.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59