linker error when function definition is outside class - c++

I have files::
//ClassA.h
#ifndef ClassA_H
#define ClassA_H
#pragma once
class ClassA
{
public:
void func1(){
}
ClassA(void) {
}
~ClassA (void) {
}
};
#endif
//ClassA1.h
#include "ClassA.h"
class ClassA1 {
ClassA<2> b;
};
//ClassA1.cpp
#include "ClassA1.h"
//main_file.cpp
#include "ClassA1.h"
#include "iostream"
int main (int argc , char** argv) {
std::cout<<"in main"<<std::endl;
}
So this compiles fine...As soon as i define function of class ClassA outside the class in Class.h i get following error during build
1> LINK : c:\users\adudeja\documents\visual studio 2010\Projects\Test\Debug\Test.exe not found or not built by the last incremental link; performing full link
1>ClassA1.obj : error LNK2005: "public: void __thiscall ClassA::func1(void)" (?func1#ClassA##QAEXXZ) already defined in main_file.obj
1>ClassA1.obj : error LNK2005: "public: __thiscall ClassA::ClassA(void)" (??0ClassA##QAE#XZ) already defined in main_file.obj
1>ClassA1.obj : error LNK2005: "public: __thiscall ClassA::~ClassA(void)" (??1ClassA##QAE#XZ) already defined in main_file.obj
1>c:\users\adudeja\documents\visual studio 2010\Projects\Test\Debug\Test.exe : fatal error LNK1169: one or more multiply defined symbols found
So what is the difference between defining function outside class and inside class.
Below is the non working code...
#ifndef ClassA_H
#define ClassA_H
#pragma once
class ClassA
{
public:
void func1();
ClassA(void);
~ClassA(void);
};
void ClassA::func1(){
}
ClassA::ClassA(void) {
}
ClassA::~ClassA (void) {
}
#endif

So what is the difference between defining function outside class and inside class.
When you define it in the class body it is implicitly inline, and an inline function can be defined in multiple files.
A non-inline function must be defined exactly once only.
So either put the non-inline definition into a single .cpp file, not in a header included by multiple files, or define it with the inline keyword.

OK, let's see...
In your example, no function is defined outside the class declaration.
Both ClassA1.cpp and main_file.cpp "see" the definition of ClassA. Since all functions defined inside a class declaration are considered inline, i.e. the linker does not see it as a seperate function at all, and has nothing to complain about.
But if you put the definition of e.g. func1() outside the class declaration (but still in ClassA), it's no longer considered inline, it's a seperate function. But as it is still visible to two compilation units, it gets compiled in both translation units.
So when you attempt to link the two object files together, you got two instances of func1(), and the linker complains.
The solution is to either:
define a function inside the class declaration, or
define the function in one seperate translation unit (ClassA.cpp), and link with that.
Using templates limits your options somewhat, as template code must be visible to each translation unit it is used in, i.e. you cannot just declare it in a header and implement it elsewhere, leaving you with only option 1. above.
Post-code-review:
ClassA.hpp:
#ifndef ClassA_HPP
#define ClassA_HPP
class ClassA
{
public:
ClassA();
~ClassA();
void func1();
};
#endif
ClassA.cpp:
#include "ClassA.hpp"
void ClassA::func1()
{
// ...
}
ClassA::ClassA()
{
// ...
}
ClassA::~ClassA()
{
// ...
}
ClassA1.hpp:
#ifndef ClassA1_HPP
#define ClassA1_HPP
#include "ClassA.hpp"
// Your example still assumed that ClassA is a template,
// so I twisted that into an inheritance instead since
// ClassA isn't a template anymore, and if it *were* a
// template, it would change things significantly.
// Perhaps trying too much at once?
class ClassA1 : public ClassA
{
// ...
};
#endif
ClassA1.cpp:
#include "ClassA1.hpp"
// ...
main_file.cpp:
#include "ClassA1.hpp"
#include <iostream>
int main( int argc, char * argv[] )
{
std::cout << "in main" << std::endl;
return 0;
}

Related

How can I call member functions from member template functions without declaring them in the entry point file?

I have a struct containing two functions, one of which is a template function that calls the other. For the sake of organization, I'd like to separate these member functions into separate implementation files instead of defining them all in main.cpp. Visual Studio throws an unresolved external symbol error.
header.hpp:
#pragma once
struct Structure {
void function();
template<bool> void templateFunc();
Structure();
};
implementation.cpp:
#include "header.hpp"
void Structure::function() { return; }
main.cpp:
#include "header.hpp"
template<bool N> void Structure::templateFunc() { return function(); }
Structure::Structure() {}
int main() {
Structure object;
object.function(); // no error
object.templateFunc<0>(); // unresolved external symbol
}
LNK2019: unresolved external symbol 'public: void __cdecl Structure::function(void)' referenced in function 'public: void __cdecl Structure::templateFunc<0>(void)'
When I define the function in main, it compiles and runs.
main.cpp:
#include "header.hpp"
void Structure::function() { return; } // defined in main
template<bool N> void Structure::templateFunc() { return function(); }
Structure::Structure() {}
int main() {
Structure object;
object.function(); // no error
object.templateFunc<0>(); // no error
}
I was initially under the suspicion that my compiler was excluding implementation.cpp, but it fails to compile when syntax errors are present. Oddly, I don't receive a multiple declaration error when the function is defined in both files. I tried reprogramming this from scratch on another device and encountered the same error. I've ensured everything is explicitly included in compilation.
The code I'm hoping for is functionally identical to the code I've found works, but this example represents a larger project I'd like to organize.
Why is this happening? How can I define this function in a separate file?

C++: Multiple definition error when including parent class?

I am writing a simple banking program with derived classes and I am running into a Multiple definition of <method name> error when including parent class.
Keep in mind that I just started coding in C++ yesterday, and moving over from Java/PHP, handling headers/definitions is a bit confusing for me. Please correct anything you see wrong!
Here is a sample of my files/code:
Files
Account.h
Account.cpp (Super)
ChequingAccount.cpp (Child)
SavingsAccount.cpp (Child)
The error is reproduce-able when including the parent class (Account.cpp) into any file. I have reduced my code by a lot, but it should give you an idea of how I am handling inheritance.
To clarify, when I #include the child classes to any file (ChequingAccount.cpp) works fine, and inherited functions work as expected. However, when I #include the parent class (Account.cpp) breaks the compiler with the Multiple definition of <method name> error for all methods.
Again, I am not sure if this is the proper way to do it, but this is what I understand from tutorials I have found.
Code
Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
protected:
double m_balance;
public:
Account(double balance); // Constructor.
virtual ~Account(); // Destructor.
// Accessor Methods.
double getBalance() const;
// Mutator Methods.
virtual void withdrawFunds(double amount);
void depositFunds(double amount);
};
#endif
Account.cpp (Superclass)
#include "Account.h"
Account::Account(double balance = 0)
{
m_balance = balance;
}
Account::~Account()
{
// TODO: Delete this data structure...
}
double Account::getBalance() const
{
return m_balance;
}
void Account::withdrawFunds(double amount)
{
m_balance -= amount;
}
void Account::depositFunds(double amount)
{
m_balance += amount;
}
ChequingAccount.cpp (Child)
#include "Account.h"
class ChequingAccount: public Account
{
public:
ChequingAccount(int id, int userId, double balance) : Account(id, balance){};
void withdrawFunds(double amount)
{
// Override parent method.
}
};
Any help would be greatly appreciated! Thank you!
When you #include "some file.cpp", you are directing the compiler to copy the contents of that cpp file to that point in the program. This will create two compiled versions of your "some file" which will lead to "Multiple Definitions."
First of all, "identical" functions declared in base class and sub-class will not cause multiple definition error.
Here is just one example and explanation aiming to help you understand my point:
main.cpp
class father{
void fun();
}
void father::fun(){}
class son : public father{
void fun();
}
void son::fun(){}
int main()
{
return 0;
}
You compile it, and definitely no multiple definition error. In Java, we define functions within classes. In C++, only inline functions are defined within classes and others are declarations, which can be declared whatever times you like. See the definition syntax : father::fun son::fun. These actually define two different functions, one is in father and the other is in son. So there are no multiple definition error. Once more, in class declarations you can only define inline functions and can only declare non-inline functions. So there are on multiple definition errors at all. This just aims to help you understand it in a grammar way.
BTW, if compiler failed to inline, there would be no multiple definition error too because even though you define inline functions in header files and include the files anywhere, inline functions are of internal linkage.
I compiled your codes and got different errors regarding your defined constructors. Anyway, including cpp files using "include" means you don't get the point of implementation file and interface file.
You need to declare the child's method as a member of the child class explicitly in the child's .cpp file as well. See below:
ChequingAccount.cpp (Child)
#include "Account.h"
class ChequingAccount: public Account
{
public:
ChequingAccount(int id, int userId, double balance) : Account(id, balance){};
void ChequingAccount::withdrawFunds(double amount)
{
// Override parent method.
}
};
You already have void Account::withdrawFunds(double) defined when you define void ChequingAccount::withdrawFunds(double).
Try virtual void ChequingAccount::withdrawFunds(double)
The virtual keyword is similar to overriding in Java.
In short, you should not include a cpp file.
The reason you get a multiple definition error actually has nothing to do with class inheritance.
Consider a simple example:
add.h:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
add.cpp:
#include "add.h"
int add(int a) { return a + 1; }
main.cpp:
#include "add.h"
int main() { return add(-1); }
The way C++ dealing with #include directive is simply to copy-paste the included file and replace the #include line. So if we expand the above files manually, we will get something like:
add.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
main.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int main() { return add(-1); }
which will work just fine. (We are allowed to have multiple declarations of a function)
However, if you decide to include the .cpp file instead of the .h file like the code below:
main.cpp:
#include "add.cpp" // notice here
int main() { return add(-1); }
And if you expand it as we just did:
add.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
main.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
int main() { return add(-1); }
You will see the code includes multiple definitions of the function add, one of which is in add.cpp and the other one is in main.cpp. When linking these two files together (each .cpp file is compiled separately using a compiler and then linked together using a linker), the linker will be confused by two definitions of add and doesn't know which one to use, so it will start to complain.

Why do C++ member functions defined in a class not produce duplicate symbols, whereas they do in C?

C Example
bb.c:
#include "bb.h"
#include <stdio.h>
void bb() {
printf("aa()...\n");
aa();
}
main.c:
#include "aa.h"
#include "bb.h"
int main(int argc, const char** argv) {
aa();
bb();
return 0;
}
aa.h:
#ifndef aa_h
#define aa_h
#include <stdio.h>
void aa() {
printf("aa()...\n");
}
#endif // aa_h
bb.h:
#ifndef bb_h
#define bb_h
#include "aa.h"
void bb();
#endif // bb_h
C Result
Compiled with clang main.c bb.c:
duplicate symbol _aa in:
/var/folders/f2/2w4c0_n519g8cd2k6xv66hc80000gn/T/main-OsFJVB.o
/var/folders/f2/2w4c0_n519g8cd2k6xv66hc80000gn/T/bb-OkcMzn.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
C++ Example
b.cpp:
#include "b.hpp"
void b::do_something_else() {
std::cout << "b::do_something_else() being called..." << std::endl;
a a;
a.doit();
}
main.cpp:
#include "a.hpp"
#include "b.hpp"
int main() {
a a;
b b;
a.doit();
b.do_something_else();
return 0;
}
a.hpp:
#ifndef a_hpp
#define a_hpp
#include <iostream>
class a{
public:
void doit() {
std::cout << "a::doit() being called..." << std::endl;
}
};
#endif // a_hpp
b.hpp:
#ifndef b_hpp
#define b_hpp
#include "a.hpp"
#include <iostream>
class b{
public:
void do_something_else();
};
#endif // b_hpp
C++ Result
The above compiles fine with clang++ main.cpp b.cpp and the output to the program is:
a::doit() being called...
b::do_something_else() being called...
a::doit() being called...
Questions
Why does the duplicate error not occur with the C++ version?
Does the fact that the function void a::doit() is defined in the header file rather than a source file mean that the compiler will automatically inline the function?
In C++ class methods are not top-level symbols, but are effectively scoped names within their class hierarchy.
This means that you have defined in C++ two doit() methods, a::doit() and b::doit()
In C, you have attempted to define one aa() function twice.
Note that C++ will give an error too if you define the doit() method twice, within the scope of the same class.
#include <iostream>
class a {
public:
void doit() {
std::cout << "hello" << std::endl;
}
void doit() {
std::cout << "goodbye" << std::endl;
}
};
leads to
ed.cpp:11:8: error: ‘void a::doit()’ cannot be overloaded
void doit() {
^
ed.cpp:7:8: error: with ‘void a::doit()’
void doit() {
^
In your C example, aa is defined twice, which violates the "one definition rule". This would be equally true if it were C++.
In your C++ example, a::doit is defined twice, but it is implicitly declared inline. Member functions defined within a class are implicitly inline per [dcl.fct.spec]/3:
A function defined within a class definition is an inline function. ...
inline functions are an exception to the one definition rule (in fact, this is the only meaning of inline required by the standard) per [basic.def.odr]/5.
There can be more than one definition of a ... inline function with external linkage (7.1.2) ... in a program, provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. ...
The requirements essentially boil down to a requirement that the definitions be identical in every translation unit where they appear.
Had you declared aa as inline, similar rules would have applied and your code would have compiled and worked as expected.
Why does the duplicate error not occur with the C++ version?
Because there is no duplication. C++ member functions are scoped by the class they are defined in. b::doit() isn't a duplicate of a::doit().
Does the fact that the function void a::doit() is defined in the header file rather than a source file mean that the compiler will automatically inline the function?
No, but it means it is possible.

Unable to inline functions even if put in header c++

I am having trouble inlining member functions. My code is as follows:
Main.cpp
#include "Foo.h"
int _tmain(int argc, _TCHAR* argv[])
{
Foo foo;
int a = foo.myInlinedFunc(2);
}
Foo.h
class Foo
{
public:
Foo(void);
~Foo(void);
inline int myInlinedFunc(int value);
};
Foo.cpp
#include "Foo.h"
Foo::Foo(void)
{
}
Foo::~Foo(void)
{
}
int Foo::myInlinedFunc(int value)
{
return value * value;
}
I get the following error:
Tester.obj : error LNK2019: unresolved external symbol "public: int __thiscall Foo::myInlinedFunc(int)" (?myInlinedFunc#Foo##QAEHH#Z) referenced in function _wmain
1>E:\Debug\Tester.exe : fatal error LNK1120: 1 unresolved externals
I have searched google for answers, but the only answers that show up, tells me that I should put the inline keyword in the header-file where it already is.
You need to put the function body, i.e. the definition, in the header file.
Your header needs to read like this:
Foo.h
class Foo
{
public:
Foo(void);
~Foo(void);
inline int myInlinedFunc(int value)
{
return value * value;
}
};
And naturally you also have to remove the definition of myInlinedFunc from Foo.cpp.
Or, if you prefer, you can write your header code like this:
Foo.h
class Foo
{
public:
Foo(void);
~Foo(void);
int myInlinedFunc(int value);
};
inline int Foo::myInlinedFunc(int value)
{
return value * value;
}
But the bottom line is that if you need your function inlined, and available to other translation units, its definition must be placed in the header file.
The C++ FAQ explains this and even predicts your unresolved external error.
If you want to share the inlined function (be usable outside the class it is in), the function must must go into the header. It doesn't need to go into top part of the header. Put it outside of the class declaration but in the same *.h file.
The source of functions' definitions need to be available for the compiler if you want to have them inlined. You can keep it in the header, or have it in a .cpp file which you include in the header.
For example, this would be Foo.h
#ifndef Foo_h
#define Foo_h
class Foo
{
public:
Foo(void);
~Foo(void);
inline int myInlinedFunc(int value);
};
#include "Foo.cpp"
#endif Foo_h
You can keep definition of the function in Foo.cpp
inline int Foo::myInlinedFunc(int value)
{
return value * value;
}
To use the class just include Foo.h where you need it. You don't need to compile Foo.cpp separatly.
You can do 1 of 2 ways
Put definition of the inline function (in your example is myInlinedFunc) in the header file
If you want to put definition of the function in another file, let add the following line at the end of the header file
#include "Foo.cpp"
And in Foo.cpp, add this line at the top of file
#include "Foo.h"

multiple declaration error- virtual functions

I have observer.h , client.h and field.h files.
In observer.h there is Subject class which has
// observer.h
class Subject {
public:
virtual ~Subject(){};
Subject(){};
virtual void Attach(Observer*);
virtual void Detach(Observer*);
virtual void Notify(bool _value);
virtual bool getCheckedIn(){};
private:
vector < Observer* > _observers;
};
#ifndef CLIENT_H
#define CLIENT_H
#include "Field.h"
class Client : public Subject {
public:
Client(string _name, Field *_field) : client_name(_name) ,field(_field) , checked_in(false) {}
void setCheckedIn(bool _value){
checked_in = _value;
Notify(_value);
}
void enterRow(string _row_name){
field->deneme();
setCheckedIn(true);
}
bool getCheckedIn(){ return checked_in;}
private:
bool checked_in;
string client_name;
Field *field;
};
#endif // CLIENT_H
#ifndef Field_H
#define Field_H
#include "CreateRow_absFac.h"
#include "observer_pattern.h"
#include <vector>
#include <string>
using namespace std;
// Template Class
class Field{
public:
Field();
// Template method
void field_creator();
virtual void setAbstractRow() = 0;
protected:
FarmFactory *abstract_row1;
FarmFactory *abstract_row2;
FarmFactory *abstract_row3;
Rows *row1 ;
Rows *row2 ;
Rows *row3 ;
Sensor sensor1;
};
When compiled , got this error :
ld: duplicate symbol Subject::Notify(bool) in /Users/barisatamer/Desktop/se311/PROJECT/build/PROJECT.build/Debug/PROJECT.build/Objects-normal/x86_64/Field.o and /Users/barisatamer/Desktop/se311/PROJECT/build/PROJECT.build/Debug/PROJECT.build/Objects-normal/x86_64/main.o
If I remove virtual functions it compiles without error. What is the problem with virtual functions ?
We can't actually see it here, but the problem is probably that you defined Subject::notify(bool) in a header file (your observer.h just declares it, it doesn't define it) and you included that header file in both Field.cpp and main.cpp, so you get multiple definitions. The fix is to move the definition into a source file so its only defined once.
General rule -- DECLARE things in header files, DEFINE them in non-header source files. Note that include guards are irrelevant here -- they prevent something being declared multiple times in a single compilation unit, but what's needed is to avoid defining something multiple times in different compilation units.
Try keeping header guards even for your observer.h. BTW, Why aren't you overriding virtual functions in the derived class ?
Apparently you have an ODR violation. Why did you get away with non-virtual functions? Possibly because you defined them inline (e.g. in class). As it was suggested, check the include guards and function definitions.