Class declarations in header files - c++

Ive been using c++ for some months now but Ive come across an error when I use header and source code files. I create a source code file
that contains a class gun(example not actual program):
class gun
{
private:
int stuff;
public:
void doStuff();
};
void Gun::doStuff()
{
cout << stuff << endl;
}
and then i created a header file and declared the class like this:
class gun;
then in my main source file i do this:
int main()
{
gun *mygun = new gun;
mygun->doStuff();
return 0;
}
however when i try to execute it i get the error:
invalid use of incomplete type 'class gun' and i think the problem is how i declared it in the header, did i do it wrong? how was i meant to do it? thanks.
Thanks Everyone that helped! I understand now, i thought that only the forward declaration
went into the header file, thanks for all your answers!

You seem to be going about seperating the implementation and header file the wrong way. Forward declarations should not go in the header file. The entire declaration should! This is how your code should be structured
Gun.hpp
#pragma once
class Gun
{
private:
int stuff;
public:
void doStuff();
};
Gun.cpp
#include "Gun.hpp"
#include <iostream>
using std::cout;
using std::endl;
void Gun::doStuff()
{
cout << stuff << endl;
}
main.cpp
int main()
{
Gun *mygun = new Gun;
mygun->doStuff();
delete mygun; // <-- remember this!
return 0;
}
the separation of header and implementation is crucial in C++ and other languages! You should only declare the class in the header along with its full interface (as above) and include all implementation details in the .cpp file (as above :)

The entire declaration of the gun class needs to be in the header file. What you declared in the header file is a forward declaration, which is not enough by itself to create an instance of the class. Forward declarations are useful for allowing other code to declare pointers only, since the compiler does not need to know the full details just to declare a pointer. But a forward declaration can't be used for creating actual object instances of the class. That is why you are getting errors about an incomplete type. From main()'s perspective, it has no idea what gun actually looks like, so it can't create a full instance of it.
The implementation of the methods for the gun class needs to be in the gun's source file, which can #include the header file to validate and access the class members.
gun.h
#ifndef gun_h
#define gun_h
class gun
{
private:
int stuff;
public:
void doStuff();
};
#endif
gun.cpp
#include "gun.h"
#include <iostream>
void gun::doStuff()
{
std::cout << stuff << std::endl;
}
Now, in main() (or any other source file), you can #include the header file and use the class as needed:
#include "gun.h"
int main()
{
gun *mygun = new gun;
mygun->doStuff();
delete mygun;
return 0;
}

In gun.h
#ifndef GUN_H_
#define GUN_H_
// You can use #pragma once too here
class gun
{
private:
int stuff;
public:
void doStuff();
};
#endif
In gun.cpp file
#include "gun.h"
void gun::doStuff()
{
cout << stuff << endl;
}
and then main.cpp
#include "gun.h"
int main() {
//your code using the class
gun *mygun = new gun;
mygun->doStuff();
return 0;
}
and you can compile and test using
g++ -o prg_name gun.cpp main.cpp && ./prg_name

Related

Member function definition outside the class

Firstly, I am giving the codes. Then I am explaining the problem I am facing.
main.cpp
#include <iostream>
#include "acc.h"
using namespace std;
class mem;
int main()
{
show();
return 0;
}
acc.h
#ifndef ACC_H
#define ACC_H
#include "acc.cpp"
void show();
class mem{
int a;
public:
void showa();
void seta(int A);
};
#endif
acc.cpp
#include <iostream>
using namespace std;
void mem::showa(){cout<<a<<endl;}
void mem::seta(int A){a = A;}
void show()
{
mem m;
m.seta(22);
string ss;
cin>>ss;
cout<<"MY name is "<<ss<<" ";
m.showa();
}
"mem" class I declared in "acc.h" file already and added that "acc.h" into acc.cpp file also. But when I am calling that class from a function. It can't response. Showing "a" and "mem" not declared. How can I perfectly link that class definition and member functions of that class so that calling member functions of that class from another function can't create any problem?
If you remove the #include "acc.cpp" from the acc.h file it should compile without any errors. I tried and it compiles for me. I am using Visual Studio 2010 for the same.
Other than this, few more comments:
You can use #pragma once in you header file instead of #ifndef/#define macros. The former is more cleaner.
You dont need to forward declare class mem before main() as you are already including acc.h.
the show() can be moved to where main() is defined making the acc.h/acc.cppfiles dedicated for the mem class.
A header file should always be named after the class it is holding i.e. mem.h/mem.cpp in your case. This informs which file contains which class even without opening the 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.

C++: Class method using function defined in main

So I have a class:
class MyClass
public:
printSomeStuff() { //Including implementation here to save space
print(data);
}
private:
int data;
And a main program, with a template function defined outside:
template<typename T>
void print(T val) {
cout << val;
}
int main() {
MyClass a;
a.printSomeStuff();
}
The idea is that I could move MyClass somewhere else and be fine, but a new print function would need to be defined based on the scenario. Typically this would just be a cout.
If I try to actually use this style of coding, though, I get an error because print is not defined in MyClass.cpp.
How should I address this issue?
You should move your print() function into a header (and a suitable namespace) and include it into the translation units where it is needed, e.g.:
// print.h
#ifndef INCLUDED_PRINT
#define INCLUDED_PRINT
#include <iostream>
namespace utilities {
template <typename T>
void print(T const& val) {
std::cout << val;
}
}
#endif
You'd then include this header into the translation where it is used, e.g.
// MyClass.h
#ifndef INCLUDED_MYCLASS
#define INCLUDED_MYCLASS
#include "print.h"
class MyClass
public:
printSomeStuff() { //Including implementation here to save space
utilities::print(data);
}
private:
int data;
};
#endif
Put your template definition in its own header file and include it in your class implementation file.
That said, with something as trivial as printing, it may be must as easy to do it in the printSomeStuff method entirely. The extra indirection isn't really buying you anything.
The header in which print template is defined has to be accessible from the header in which MyClass is defined, but not necessarily from main, so you could move it to a separated header and include it from MyClass.hpp or even MyClass.cc

C++ what to code if i put a class after main() function

I'm watching some video tutorials on C++ and i know you must define a function / class before it is used or called. But I like having my main() function at the top, and everything else below the main function. I know if i define a function below the main function I must declare it before it is used, but what about a class? What do I need to put above my main function to use my class below the main function.
#include <iostream>
using namespace std;
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
I tried defining my class by placing this right before main():
class ClassOne;
but it doesn't work.
This is why header files are normally used in C++. When you're saying ClassOne one, the compiler needs to know what the class looks like to create an object of that type. It's not enough to know that the class exists somewhere (that is enough if all you want is a pointer). So the compiler needs to already have read the definition of the class.
Your class has to be defined before it is first used. Without putting it explicitly before main, the usual way is to create a header file. So you create ClassOne.h with the class declaration, and you have #include "ClassOne.h at the top of your file. In this situation the actual methods of the class would normally be in another source file, ClassOne.cpp.
A class MUST be "complete" when you create an instance of it. So there is no way you can use the class before you have defined the whole content of the class.
It is possible to do something like this:
class ClassOne;
ClassOne* make_class_one();
void use_class(ClassOne *x);
int main()
{
ClassOne* one = make_class_one();
use_class(one);
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
ClassOne* make_class_one()
{
return new ClassOne; // Bad idea, use uniqe_ptr, but I'm lazy.
}
void use_class(ClassOne *x)
{
x->coolSaying();
}
But in general, we don't want to do that.
One scenario where the class definition after the main() function makes sense:
#include <iostream>
using namespace std;
void f();
int main()
{
f();
return 0;
}
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
void f()
{
ClassOne one;
one.coolSaying();
}
(note: all other answers are correct, but you may find this useful)
I discovered this idiom to invert the order of main and secondary function classes. I use to share small code with colleagues, everybody expects the core of the code (i.e. main) to be on top so they can edit it quickly. It works with classes and functions (without need of declaration) of course. Usually I can leave the preamble (first #includes) because those have include guards in most cases.
#include <iostream>
using namespace std;
#ifdef please_see_definitions_below_main
int main()
{
ClassOne one;
one.coolSaying();
return 0;
}
#else
class ClassOne
{
public:
void coolSaying()
{
cout << "Cool stuff yo!" << endl;
}
};
#define please_see_definitions_below_main
#include __FILE__
#endif
I use the tag please_see_definitions_below_main so it serves as comment also, but if you don't like it you can use something shorter, like AFTER.
You cannot create an actual instance of the type (variable, value member) until the type is fully defined, as its size is not known. There is no way around that, but there is a lot you can already do with a pointer to an incomplete type.

How to forward declare a custom constructor?

Note: I have found the issue with how my Xcode was compiling the below and it appears unrelated to the topic discussed herein. When I have more details I will provide them here.
I recommend voting to close my question as "too localized" since it was an Xcode problem, unrelated to the c++ code itself. Many thanks for the help all the same as I did learn from the answers.
The below question (now answered and resolved) was caused by a confusing exclusion of a file from the Xcode target, thus there were no compiler errors even though the file had problems.
I have a pure virtual interface and want to define its factory method, which returns a subclass of this interface. This works fine:
struct MyVirt{
...all virtual stuff
};
class SubVirt; //forward declaration allows factory:
MyVirt*CreateClass(){
return new SubVirt;
}
Update: Some of the comments say that forward declare is not enough to achieve the above, but that's not correct. You can accomplish the above fine without the full definition of the SubVirt class.
Now, what I want to do is have a custom constructor that takes arguments. As such:
MyVirt*CreateClass(){
return new SubVirt(arg 1, etc);
}
The problem is that a class forward declaration is no longer sufficient. It needs to see the class definition or its header. This means I can either move the factory method to the file where SubVirt is defined, or I have to include that file in the above file, which creates a circular dependency.
Is there a way to forward declare the custom constructor instead? That would make it all much simpler.
Your CreateClass function looks odd, you miss () in function definition. Should be like this:
MyVirt* CreateClass()
{
return new SubVirt(arg 1, etc);
}
When return a pointer, compiler needs to know the concrete type and constructor, so forward declare is not enough.
What you could do is:
in header file: forward declare SubVirt and CreateClass function
cpp file: include MyVirt.h and define CreateClass function
Separate declaration from implementation, like everyone does.
MyVirt.h:
struct MyVirt{
...all virtual stuff
};
MyVirt.cpp:
#include "MyVirt.h"
Implementation of MyVirt
SubVirt.h:
#include "MyVirt.h"
struct SubVirt : MyVirt {
...all SubVirt stuff
};
SubVirt.cpp:
#include "SubVirt.h"
Implementation of SubVirt
Factory.h:
struct MyVirt;
MyVirt *CreateClass();
Factory.cpp:
#include "SubVirt.h"
MyVirt *CreateClass() { return new SubVirt() }
This can be accomplished by separating the declaration and implementation.
The key here is to put the definition/implementation above the includes. Suppose you want to separate the classes A and B create two files like the following:
A.hpp
#ifndef A_HPP
#define A_HPP
struct B; // fwd. decl.
struct A {
int v;
A(int v) {
this->v = v;
}
B* createB();
};
#include "B.hpp"
A* B::createA() {
return new A(v);
}
#endif A_HPP
B.hpp
#ifndef B_HPP
#define B_HPP
struct A; // fwd. decl.
struct B {
int v;
B(int v) {
this->v = v;
}
A* createA();
};
#include "A.hpp"
B* A::createB() {
return new B(v);
}
#endif // B_HPP
main.hpp
#include <A.hpp>
#include <B.hpp>
#include <iostream>
int main(int argc, char *argv[]) {
A a(42);
std::cout << a.createB()->createA()->v << std::endl;
return 0;
}
You are of course free to move the implementation into a cpp file instead. This is only the basic recipe which shows how circular dependencies can be solved even for templated classes and functions.
http://codepad.org/IsBzQANX