Use g++ or CC to compile multiple C++ files - c++

Good Day,
I have tried to lookup how to compile several C++ files on a *nix command line.
I've tried these two links
Using G++ to compile multiple .cpp and .h files
Using G++ to compile multiple .cpp and .h files
I have a simple abstract class:
// Base class
class Shape
{
public:
// pure virtual function providing interface framework.
virtual int getArea() = 0;
void setWidth(int w) {
width = w;
}
void setHeight(int h) {
height = h;
}
protected:
int width;
int height;
};
Then a derived one:
// Derived classes
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
Here is the driver:
#include <iostream>
using namespace std;
int main(void)
{
Rectangle Rect;
Rect.setWidth(5);
Rect.setHeight(7);
// Print the area of the object.
cout << "Total Rectangle area: " << Rect.getArea() << endl;
return 0;
}
This is a simple one, so I don't need a makefile, but this is what I've tried:
> g++ Shape.cc - This creates a Shape.o
> g++ Shape.cc Rectangle.cc ShapeDriver.cc - This creates an error
> g++ ShapeDriver.cc Shape.cc Rectangle.ccc - This creates an error
It turns out that Rectangle.cc is not recognizing the width and height definitions, which makes sense.
What else do I need to do to get this to compile? I'm a total C++ noob.
TIA,
coson

You need to add the following to the different files...
Top of Rectangle.cc
#include "Shape.cc"
Top of ShapeDriver.cc
#include "Rectangle.cc"
Also, in your third gcc line, you have a typo
g++ ShapeDriver.cc Shape.cc Rectangle.ccc - This creates an error
It should have been Rectangle.cc
What your problem is, is that in each of your files, the different classes have never been defined, so they don't know how to use them. Like.... "Rectangle" first needs to know what a "Shape" is before it derives from it. You should be using .h files in between w/ the class definitions, and including them in the other .cc files so they know the other class structures they are calling on.

Related

Error on .h and .cpp file separation, but no error on using just a .h file. What am I doing wrong?

I'm a C++ noob, so please go easy on me if my doubt seems too trivial.
#pragma once
class cube
{
public:
double getVolume();
double getSA();
void setLength(double length);
private:
double length_;
};
This is my header file cube.h ^^^
#include "cube.h"
double cube::getVolume()
{
return length_ * length_ * length_;
}
double cube::getSA()
{
return 6 * length_ * length_;
}
void cube::setLength(double length)
{
length_ = length;
}
This is cube.cpp and the next is main.cpp
#include "cube.h"
#include <iostream>
int main()
{
cube c;
c.setLength(3.48);
double vol = c.getVolume();
std::cout << "Vol: " << vol;
return 0;
}
Question 1: So when I include the implementation in .h file itself without using .cpp, the code runs as expected. But when I separate the .h and .cpp files, I get an error saying: 'undefined reference to cube::setLength(double)', 'undefined reference to cube::getVolume()'' and 'exited with code=1 in 0.47 seconds'.
I ran it on VS Code and just set it up, and just ran a simple cin/cout and a hello world program. Is there something wrong I'm doing with the code itself or is it an error due to VS Code? Do note that this problem occurs only when I separate the .h and .cpp files.
Question 2: Why even separate the .h and .cpp files?
Edit 1: As #KamilCuk pointed out, the problem might be in linking the main.cpp and cube.cpp files, but I have no clue how you 'link' the cpp files for compilation?
Edit 2: I just might be compiling it the wrong way. I usually just click the Code Runner enabled run button on the top right, but I have no clue how to compile two files at once.
Try to do this. This worked for me and gave desired result:
g++ main.cpp cube.cpp -I./ -o cube.out
You can implement in .h file inline as well and can be make your code work. But for more complex classes better to separate the implementation in .cpp and .h
Also its a good practice to guard header file for multiple definitions:
#ifndef _CUBE_H_
#define _CUBE_H_
class Cube
{
public:
double getVolume();
double getSA();
void setLength(double length);
private:
double length_;
};
#endif //_CUBE_H_
Below link provided details of how to build multiple C++ files using VSCode.
https://dev.to/talhabalaj/setup-visual-studio-code-for-multi-file-c-projects-1jpi

LNK2019 how to solve in the case? Everything seems to be correct [duplicate]

This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 5 years ago.
I have that common LNK2019 error and can not figure out what is wrong.
Here is my Solution Explorer:
Here is my Rectangle.cpp:
class Rectangle
{
public:
int getArea()
{
return this->width*this->height;
}
int width;
int height;
};
Here is my Rectangle.h:
#pragma once
class Rectangle
{
public:
int getArea();
int width;
int height;
};
Here is my Functions.cpp:
#include <iostream>
#include "Rectangle.h";
using namespace std;
int main()
{
Rectangle r3{ 2, 3 };
cout << r3.getArea();
return 0;
}
I am very new to C++ and it seems I did everything correctly, but still I am getting an error.
Rectangle.cpp should be like this:
#include "Rectangle.h"
int Rectangle::getArea() {
return this->width*this->height;
}
You shouldn't redefine the class definition in the source file, since you already have it in the header file!
When you want to write the body of a class function, you need to write it this way :
#include "Rectangle.h"
int Rectangle::getArea()
{
return this->width*this->height;
}
You do not need to redefine your class into the cpp file.
You define everything inside the header (.h, .hpp), you include it inside the cpp file (#include "Rectangle.h") but you must not redeclare everything in the header file.
By the way, since you are writing a method, you can access member variables directly by width and you do not need to use this->width.
However, I recommand you to use a convention when you are writing your own classes.
My convention is to prefix member variable by a m. (In your case it gives you mWidth or mHeight).
There is other people that have other conventions like m_variable or variable_.

Trying with C++ graphics, i have included the header files, even getting error?

I am trying to learn C++. Presently I am following a book called “Object Oriented Programing in C++” fourth edition (by Robert Lafore). In this book on page number 225 there is an example about object and classes. I have share the example below, and have manage to download included files and extracted them in to the project folder.
So now my project file is contains a file called “msoftcon.c ” and “msoftcon.h”. When I try to compile the project I get an error “undefined reference to ‘init_graphics()’ ”, whereas this function is very much in msoftcon.c.
Example is as follow:
#include <iostream>
#include "msoftcon.h"
using namespace std;
class circle
{
protected:
int xCo, Yco; //coordinates of center
int radius;
color fillcolor; //color
fstyle fillstyle; //fill pattern
public:
void set(int x, int y, int r, color fc, fstyle fs)
{
xCo = x;
Yco = y;
radius = r;
fillcolor = fc;
fillstyle = fs;
}
void draw()
{
set_color(fillcolor); //set color
set_fill_style(fillstyle); //set till
draw_circle(xCo, Yco, radius); //draw solid circle
}
};
int main()
{
init_graphics();
return 0;
}
Most likely you failed to add msoftcon.c and the associated .h to your project. Merely unpacking it in your project directly is not enough. It needs to be actually added to the project, after which it will be compiled and linked with the other files, hopefully eliminating the error you are seeing.
Exactly how that is done depends on your setup (IDE etc.).

C++ Inheritance in Separate Files Using #include and Inclusion Guards

I am new to Stack Overflow and am teaching myself C++, but am still quite a beginner. After completing a nice chunk of the book I am using (which may be considered out dated and/or not a great book) I decided to re-enforce some concepts by trying them on my own, referencing the book only if needed, but I appear to be stuck. The concepts I am trying to tackle are inheritance, polymorphism, abstract data types (ADT), and separating the code for my classes into header files (.h) and C++ file (.cpp). Sorry in advance for the wall of text, I just want to be clear and specific where I need to be.
So, my goal is to create simple shape classes that inherit from one another where applicable. I have four classes: myPoly, myRectangle, myTriangle, and mySquare. myPoly, if I understood this concept correctly, should be an ADT since one of the methods is a pure virtual function (area method), since creating a myPoly object isn't something I would want a user of my classes to do. myRectangle and myTriangle both derive from myPoly and in turn mySquare derives from myRectangle. I've also included my test program where I planned on testing my classes. I am using Code::Blocks 10.05 and keep getting the following error when I build my test.cpp program:
undefined reference to 'myPoly::myPoly()'
I get 42 similar errors all for the methods of the myPoly class. This happens when I try to build the .cpp files for myRectangle and myTriangle too. With the research I tried to do on the problems I been running into with this little project I feel like something is wrong with my inclusion guards or my #include statements, and something isn't getting included properly or is getting included too many times. At first I was providing the .cpp file for myPoly to myRectangle and myTriangle, but read in a couple of places that including the .h file for myPoly is more efficient and some how automatically include its .cpp. If anyone can provide some insight on that, it would be greatly appreciated. I also remember something about how using quotes in your inclusion statements is different than using the angle brackets. Below are all nine files that I have made for my little project. Most of the comments are little notes or reminders to me.
myPoly.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//header file for Polygon class
#ifndef MYPOLY_H
#define MYPOLY_H
class myPoly
{
public:
//constructor
//const reference pass because the values w and h don't change and reference avoid the time it takes to copy large
// objects by value (if there were any)
myPoly();
myPoly(const float & w, const float & h);
//destructor
virtual ~myPoly();
//accessors
float getWidth();
float getHeight();
void setWidth(const float & w);
void setHeight(const float & h);
virtual float area() = 0;
private:
float width, height;
};
#endif
myPoly.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myPoly class
#include "myPoly.h"
//constructor
myPoly::myPoly()
{
setWidth(10);
setHeight(10);
}
myPoly::myPoly(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
//destructor
myPoly::~myPoly() {}
//accessors
float myPoly::getWidth() {return width;}
float myPoly::getHeight() {return height;}
void myPoly::setHeight(const float & w) {width = w;}
void myPoly::setWidth(const float & h) {height = h;}
//pure virtual functions have no implementation
//area() is handled in the header file
myRectangle.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myRectangle class
#ifndef MYRECTANGLE_H
#define MYRECTANGLE_H
#include "myPoly.h"
class myRectangle : public myPoly
{
public:
//constructor
myRectangle();
myRectangle(const float & w, const float & h);
//destructor
~myRectangle();
//this doesn't need to be virtual since the derived class doesn't override this method
float area();
};
#endif
myRectangle.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementaion file for the myRectangle class
//get a vauge compiler/linker error if you have virtual methods that aren't implemented (even if it ends up being just
// a 'stub' method, aka empty, like the destructor)
#include "myRectangle.h"
myRectangle::myRectangle()
{
setWidth(10);
setHeight(10);
}
myRectangle::myRectangle(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
myRectangle::~myRectangle()
{
}
float myRectangle::area()
{
return getWidth() * getHeight();
}
myTriangle.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for myTriangle class
#ifndef MYTRIANGLE_H
#define MYTRIANGLE_H
#include "myPoly.h"
//imagine the triangle is a right triangle with a width and a height
// |\
// | \
// | \
// |___\
class myTriangle : public myPoly
{
public:
//constructors
myTriangle();
myTriangle(const float & w, const float & h);
//destructor
~myTriangle();
//since nothing derives from this class it doesn't need to be virtual and in turn neither does the destructor
float area();
};
#endif
myTriangle.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for myTriangle class
#include "myTriangle.h"
myTriangle::myTriangle()
{
setWidth(10);
setHeight(10);
}
myTriangle::myTriangle(const float & w, const float & h)
{
setWidth(w);
setHeight(h);
}
myTriangle::~myTriangle()
{
}
float myTriangle::area()
{
return getWidth() * getHeight() / 2;
}
mySquare.h
//Practice with inheritance, polymorphism, and Abstract Data Types
//declaration file for mySquare class
#ifndef MYSQUARE_H
#define MYSQUARE_H
#include "myRectangle.cpp"
class mySquare : public myRectangle
{
public:
//constructors
mySquare();
//explicity call the myRectangle constructor within this implementation to pass w as width and height
mySquare(const float w);
//destructor
~mySquare();
};
#endif
mySquare.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//implementation file for mySquare class
#include "mySquare.h"
mySquare::mySquare()
{
setWidth(10);
setHeight(10);
}
mySquare::mySquare(const float w)
{
myRectangle::myRectangle(w, w);
}
mySquare::~mySquare()
{
}
test.cpp
//Practice with inheritance, polymorphism, and Abstract Data Types
//main class that uses my shape classes and experiments with inheritance, polymorphism, and ADTs
#include "myRectangle.cpp"
//#include "mySquare.cpp"
#include "myTriangle.cpp"
#include <iostream>
int main()
{
myPoly * shape = new myRectangle(20,20);
return 0;
}
I am very curious as to why I am getting these errors or why something I did may not be considered good/best practice, as opposed to just receiving a line of code to make my errors go away.
Your inclusion guards look fine. If they were not, you would most likely get a compiler error, including file and line number information. The error you posted seems more like a linker error.
However, there is one "problem" with your code. As a general rule, you should only #include .h files and not .cpp files.
Now to get to the solution: I am unfamiliar with Code::Blocks myself. However, I hope I can give some general information that will point you in the right direction. Some compilers I have used in the past by default allowed me to compile a single C++ file and run the program. To compile a program with more than one file, I had to create a project. (Most modern compilers force you to create a project from the start.) With this in mind, I would suggest you check out how to create a project for your program in Code::Blocks.
From a code stand point (at least what I looked through), it looks pretty good, but:
There are two things to consider:
Don't directly include cpp files. For example, in mySquare.h, #include "myRectangle.cpp" should be #include "myRectangle.h". You want to be including the interface/declarations provided in the header file that tell the program how to make the class, not just the function definitions.
Second, make sure you're compiling with all your object files. I don't know code blocks, but if you were using g++ or something like that, you'd want to do g++ main.cpp myPoly.cpp mySquare.cpp etc. for all files. An error like this may happen if you forget myPoly.cpp, for example, because no definitions for its functions would be included.
Everything looks fine, actually. It is probably just as simple as not including myPoly.obj when you link your program. I am not familiar with Code::Blocks (although I know it's fairly popular) but I assume if you just, for example, click on test.cpp and choose "Run", that Code::Blocks will try to build a program from just that one source file. You'll need to include all the relevant source files in each program that you build.
Additionally to what the otehr guys said: You are not doing inheritance right...
When you do
class Poly
{
Poly();
~Poly();
}
class Rect : public Poly()
{
Rect();
~Rect();
}
You need to declare the child's constructor the following way:
Rect::Rect() : Poly()
{
}
The child must only be constructed after the father has finished constructing.

Getting "multiple types in one declaration" error in C++

Can anyone tell me why i get a "Block.h:20: error: multiple types in one declaration" error message when compiling this file. Nothing seems to be solving this problem and I'm getting pretty frustrated.
Displayable.h
#include <X11/Xlib.h>
#include <X11/Xutil.h>
// Information to draw on the window.
struct XInfo
{
Display *display;
Window window;
GC gc;
};
// An abstract class representing displayable things.
class Displayable
{
public:
virtual void paint(XInfo &xinfo) = 0;
};
Sprite.h
#include "Displayable.h"
enum Collision {
NO_COLLISION = 0,
TOP_COLLISION,
RIGHT_COLLISION,
BOTTOM_COLLISION,
LEFT_COLLISION
};
class Sprite : public Displayable {
public:
int x, y, width, height;
Sprite();
virtual void paint(XInfo &xinfo) = 0;
Collision didCollide(Sprite *s);
};
Block.h
#include "Sprite.h"
class Block : public Sprite {
public:
virtual void paint(XInfo &xinfo);
Block(int x, int y, int width, int height);
}; <-- **This is line 20**
As is, the code looks OK. I can't see anything wrong with the particular line. However, Xlib is a C library which likes to define quite a number of macros and conventionally uses CamelCase for macros, too. That is, I would suspect that something in your declarations actually happens to be a macro which gets expanded to something the C++ compiler doesn't like. To find this problem I recommend you use the omnipresent -E flag to have a look at the preprocessed source. That is, you'd remove any -o flag (and the name following it) and -c flag but otherwise you'd essentially retain the command line. The result will be written to standard output i.e. you want to redirect the output to more/less or some file.
Alternatively, you can go about and prefix all of your names by a prefix which is unlikely to be used in any of the X11 headers, e.g. parts of some name, offensive words, etc. I tried to reproduce the problem on my system but I didn't get an error message.