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"
Related
Why if I have
in foo.h:
class Foo
{
}
void Bar(const Foo& foo);
it works but:
in foo.h:
class Foo
{
}
in bar.cpp
#include "foo.h"
void Bar(const Foo& foo);
doesn't work (unknown type name 'Foo' is its exact words)?
I don't know what about my question isn't specific and forward declarations don't work they just create a error 'duplicate symbol' so im just going to post the code im working with
in creatures.h
#ifndef CREATURES_H_
#define CREATURES_H_
#include <string>
#include "textio.hpp"
class Creature {
private:
protected:
int statBlock[10];
public:
std::string name = "foo";
Creature ();
void ai(int);
};
class Dwarf : public Creature {
private:
public:
std::string name = "Dwarf";
Dwarf (int);
void defaultDwarfGen();
};
main.cpp
#endif
#include "creatures.hpp"
#include "textio.hpp"
#include <iostream>
int main(int argc, char const *argv[]) {
Dwarf creature_1(0);
return 0;
}
textio.hpp:
#ifndef TEXTIO_H
#define TEXTIO_H
#include <iostream>
#include "creatures.hpp"
void challenge(const Creature& param);
#endif
Your problem is that you are including textio.hpp in creatures.hpp so first time that compiler see function void challenge(const Creature& param)Creature class isn't defined.
When you include createures.hppin textio.hpp CREATURES_H_ is already defined and bypass inclusion)
You can fix it deleting this include or declaring a forward definition for Creature class
In order to answer this question properly, you must provide foo.h, foo.cpp, bar.h, and bar.cpp
In short:
To make use of Bar in foo.h, foo.h must have the declaration for Bar.
To make use of Foo in bar.h, bar.h must have the declaration for Foo.
To make use of Bar in foo.cpp, foo.h or foo.cpp must have the declaration for Bar.
To make use of Foo in bar.cpp, bar.h or bar.cpp must have the declaration for Foo.
When I say, "must have declaration for", you can #include the appropriate header.
If you are trying to use Foo in Bar and Bar in Foo, then you've got a circular reference. The way we overcome this is with a forward declaration.
You can read about forward declarations here: https://isocpp.org/wiki/faq/misc-technical-issues#forward-decl
Let's say I have two files foo.h and foo.cpp
foo.h
class foo
{
public:
Foo();
~Foo();
private:
/*
Member functions
*/
static void DoThis();
/*
Member variables
*/
static int x;
protected:
};
foo.cpp
#include "foo.h"
int foo::x;
void foo::DoThis()
{
x++;
}
Can I avoid the hassle of having to declare each variable in foo.cpp again? If I removed this line int foo::x; I would get a linker error for unresolved external symbol.
Is there another way of doing this without having to type a line for each variable I'm planning to use?
You only need to re-declare static variables. If you make a variable in the class definition without making them static, you can just leave them there. Example:
foo.h
#ifndef _FOO_H_
#define _FOO_H_
class Foo{
private:
static int i; //Static variable shared among all instances
int o; //Non-static variable remains unique among all instances
public:
Foo(); //Consructor
};
#endif
foo.cpp
int Foo::i = 0; //Only static variables can be initialized when in a class
//No definition required for non-statics
Foo::Foo(){
//Constructor code here
i = 0;
};
The #ifndef block prevents the header from accidentally being included multiple times by the same source file. This is in case a header is included in another header, which, if these blocks are not present, could result in an infinite include loop and force the compiler to quit when it counts an include depth that's too high.
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.
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;
}
All code From what I've read, A1 & A2 are identical, but I don't if A3 is identical to A2. I know the code will compile since all of the A classes are tmemplated.
Note: All of the class & method declarations are in a .h file.
template <typename _Ty>
class A1 {
public:
A1();
void foo() { ... }
};
template <typename _Ty>
class A2 {
public:
A2();
void foo();
};
template <typename _Ty>
inline void A2<_Ty>::foo() { ... }
template <typename _Ty>
class A3 {
public:
A3();
void foo();
};
template <typename _Ty>
void A3<_Ty>::foo() { ... } // note: No inline keyword here.
P.S. I've seen variants of this question on stackoverflow, but not this exact question.
Yes, it's meaningful, but doesn't have much effect when combined with templates.
The major effect of the inline keyword is to tell the compiler that this function may appear with the same definition in multiple compilation units, so it needs to be flagged as "select-one" for the linker (so you don't get multiple definition errors). Templates already have this feature.
inline also is a hint to the compiler that you think the function should be inlined, but the compiler usually makes the final decision on inlining optimizations on its own.
Is inline keyword meaningful if function is defined in header file?
It is. Following project will produce linker error on both msvc and g++ BECAUSE of the omission of inline keyword:
main.cpp:
#include "a.h"
int main(int argc, char** argv){
A obj;
obj.f();
a();
b();
return 0;
}
a.h:
#ifndef A_HEADER
#define A_HEADER
class A{
public:
void f();
};
void a(){
}
void b();
void A::f(){
}
#endif
b.cpp:
#include "a.h"
void b(){
A obj;
obj.f();
a();
}
*.pro file (for Qt 4 build system):
TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .
HEADERS += a.h
SOURCES += b.cpp main.cpp
Compilation output:
cl.exe:
main.obj : error LNK2005: "void __cdecl a(void)" (?a##YAXXZ) already defined in b.obj
main.obj : error LNK2005: "public: void __thiscall A::f(void)" (?f#A##QAEXXZ) already defined in b.obj
debug\1234.exe : fatal error LNK1169: one or more multiply defined symbols found
g++:
debug/main.o: In function `Z1av':
D:\c++\1234/a.h:6: multiple definition of `a()'
debug/b.o:D:\c++\1234/a.h:6: first defined here
debug/main.o:D:\c++\1234/a.h:11: multiple definition of `A::f()'
debug/b.o:D:\c++\1234/a.h:11: first defined here
collect2: ld returned 1 exit status
make[1]: *** [debug/1234.exe] Error 1
make: *** [debug] Error 2
Now, why do you think this happens? Because compiler inserts contents of header file into *.cpp file when compiling. Since function isn't "inline", its name is made known to the linker, and each .obj/.o file will get its own unique copy of A::f() and a(). Linker won't know which you're supposed to use and will complain. If you make functions inline, everything will work fine.
However, templates are another story.