There is one header a file Rectangle.hxx
#ifndef Rectangle_included
#define Rectangle_included
#include <iostream>
#include <math.h>
#include "GetL.hxx"
using namespace std;
class Rectangle: public GetL
{
int width;
int value;
public:
Rectangle();
Rectangle(int v, int w);
Rectangle(const Rectangle& b);
int getWidth();
int getValue();
Rectangle & plus(int newval);
};
#endif //Rectangle_included
The file GetL.hxx is defined like this:
#ifndef GetL_included
#define GetL_included
#include <iostream>
using namespace std;
class GetL
{
public:
virtual int getWidth();
};
#endif //GetL_include
The file Rectangle.cxx contains various definitions:
#include <iostream>
#include <math.h>
#include "Rectangle.hxx"
using namespace std;
Rectangle::Rectangle()
{
value=0;
width=0;
}
Rectangle::Rectangle(int v, int w)
{
value=v;
width=w;
}
Rectangle::Rectangle(const Rectangle& b)
{
value= b.value;
width= b.width;
}
int Rectangle::getWidth()
{
return width;
}
int Rectangle::getValue()
{
return value;
}
Rectangle& Rectangle::plus(int newval)
{
value+=newval;
if(value>=pow(2,width))
cout<<"Overflow";
return *this;
}
But i am getting the error on compiling Rectangle.cxx.
/tmp/cclETn3R.o:Rectangle.cxx:(.text$_ZN4GetLC2Ev[GetL::GetL()]+0*8): undefined reference to 'vtable for Getl'
How can i remove it? How can i define file GetL.cxx or i don't need to?
You need to compile the different files without linking first. On UNIX compilers this is typically done using the -c option. When building the executable you then specify all the produced .o objects. Alternatively you can specify all source files at once but this is really only viable for very small projects.
You must implement GetL::getWidth(). Given your other files, you will probably implement it in GetL.cxx.
Related
When I have a class I want to use somewhere else, such as Secondaryfile.cpp, I can import it fine into another file where I create a new class, as long as I do the class definition, etc inside the .cpp file, not the header file, otherwise I get linking errors. I have tried adding things like extern "C" in the Secondaryfile.cpp but to no avail. Looking at the errors, I also thought that pershaps I shouldn't use the namespace, however, that still results in the same error.
The reason why I am doing this is that I want to import a Tertiaryfile into Mainfile which has a function with the same name as a function in Secondaryfile, so I wanted to be able to refer them as, say, Secondaryfile::add1() and Tertiaryfile::add1() and avoid any issues with the same names that way - through the use of namespaces. I want to be able to declare the Mainfile class in its header file so that I can import it and use it in a different class down the line.
In the example below, running g++ Mainfile2.cpp compiles fine, however, g++ Mainfile.cpp doesn't, instead it results in the following error:
Mainfile.cpp:(.text+0x20): undefined reference to 'Secondaryfile::Secondaryfile::Secondaryfile()'
Mainfile.cpp:(.text+0x58): undefined reference to 'Secondaryfile::Secondaryfile::getX()'
Mainfile.cpp:(.text+0x7a): undefined reference to 'Secondaryfile::Secondaryfile::Secondaryfile(int)'
My code:
Mainfile.cpp
#include "Mainfile.h"
#include <cstddef>
#include <cstdio>
Mainfile::Mainfile(char* name, Secondaryfile::Secondaryfile x)
{
this->name = name;
this->x = x;
}
Mainfile::getDoubleX(){
return this->x.getX() * 2;
}
static Secondaryfile::Secondaryfile getObj(int num){
return Secondaryfile::Secondaryfile(num);
}
int main(){
}
Mainfile.h
#ifndef MAINFILE_H
#define MAINFILE_H
namespace Secondaryfile{
#include "Secondaryfile.h"
}
class Mainfile
{
public:
char* name;
Secondaryfile::Secondaryfile x;
Mainfile(char*, Secondaryfile::Secondaryfile);
int getDoubleX();
static Secondaryfile::Secondaryfile getObj(int);
};
#endif
Mainfile2.cpp
namespace Secondaryfile{
#include "Secondaryfile.h"
}
#include "Mainfile2.h"
#include <cstddef>
#include <cstdio>
class Mainfile2{
public:
char* name;
Secondaryfile::Secondaryfile x;
Mainfile2(char* name, Secondaryfile::Secondaryfile x)
{
this->name = name;
this->x = x;
}
getDoubleX(){
return this->x.getX() * 2;
}
static Secondaryfile::Secondaryfile getObj(int num){
return Secondaryfile::Secondaryfile(num);
}
};
int main(){
}
Mainfile2.h
#ifndef MAINFILE2_H
#define MAINFILE2_H
int getDoubleX();
static Secondaryfile::Secondaryfile getObj(int);
#endif
Secondaryfile.cpp
#include "Secondaryfile.h"
#include <cstddef>
#include <cstdio>
Secondaryfile::Secondaryfile(int x)
{
this->x = x;
}
Secondaryfile::Secondaryfile()
{
this->x = 0;
}
int Secondaryfile::getX()
{
return this->x;
}
int Secondaryfile::add1(int num)
{
return num+1;
}
int main(){
}
Secondaryfile.h
#ifndef SECONDARYFILE_H
#define SECONDARYFILE_H
class Secondaryfile
{
public:
int x;
Secondaryfile();
Secondaryfile(int);
int getX();
static int add1(int);
};
#endif
There are many problems with your code.
In Mainfile.cpp you didn't specify the return type of Mainfile::getDoubleX()(it should be int)
You can only specify static member functions inside a class definition(in Mainfile.cpp, the function getObj has that qualifier). Also it should have a class scope, so the correct way of writing is Secondaryfile Mainfile::getObj(int num)
Doing namespace Secondaryfile{ #include "Secondaryfile.h"}. You shouldn't do this. Just #include "Secondaryfile.h" inside the source files is enough. You mention that you did this to prevent "linking errors", but that is probably because of the other problems in your code and in your project configuration.
You also didn't specify your compiler & IDE/cmake/makefile configs, which is essential for properly compiling and linking these header and source files.
Are you building a library or executable code? You include a main() function in your source files that doesn't do anything, which is also bad practice, because main() in C++ is an entry-point function, wich means that the compiler will look for it to create the starting point of the program1.
With these in mind, I tried to fix your code. See if this is what you had in mind:
Mainfile.cpp
//
// Created by vinicius on 21/10/2020.
//
#include "Mainfile.h"
#include <cstddef>
#include <cstdio>
Mainfile::Mainfile(char* name, Secondaryfile x)
{
this->name = name;
this->x = x;
}
int Mainfile::getDoubleX(){
return this->x.getX() * 2;
}
Secondaryfile Mainfile::getObj(int num){
return Secondaryfile(num);
}
int main() {
//Test code
printf("Hello World!\n--------\n");
Secondaryfile s = Secondaryfile();
Mainfile f = Mainfile("myname", s);
Secondaryfile myobj = f.getObj(12);
printf("Value = %d", myobj.getX());
}
Mainfile.h
//
// Created by vinicius on 21/10/2020.
//
#ifndef MAINFILE_H
#define MAINFILE_H
#include "Secondaryfile.h"
class Mainfile
{
public:
char* name;
Secondaryfile x;
Mainfile(char*, Secondaryfile);
int getDoubleX();
static Secondaryfile getObj(int);
};
#endif
Mainfile2.cpp
//
// Created by vinicius on 21/10/2020.
//
#include "Secondaryfile.h"
#include "Mainfile2.h"
#include <cstddef>
#include <cstdio>
Secondaryfile Mainfile2::getObj(int num) {
return Secondaryfile(num);
}
int Mainfile2::getDoubleX() {
return this->x.getX() * 2;
}
Mainfile2::Mainfile2(char *name, Secondaryfile x) {
this->name = name;
this->x = x;
}
Mainfile2.h
//
// Created by vinicius on 21/10/2020.
//
#ifndef MAINFILE2_H
#define MAINFILE2_H
class Mainfile2{
public:
char* name;
Secondaryfile x;
Mainfile2(char* name, Secondaryfile x);
int getDoubleX();
static Secondaryfile getObj(int num);
};
#endif
Secondaryfile.cpp
//
// Created by vinicius on 21/10/2020.
//
#include "Secondaryfile.h"
#include <cstddef>
#include <cstdio>
Secondaryfile::Secondaryfile(int x)
{
this->x = x;
}
Secondaryfile::Secondaryfile()
{
this->x = 0;
}
int Secondaryfile::getX()
{
return this->x;
}
int Secondaryfile::add1(int num)
{
return num+1;
}
Secondaryfile.h
//
// Created by vinicius on 21/10/2020.
//
#ifndef SECONDARYFILE_H
#define SECONDARYFILE_H
class Secondaryfile
{
public:
int x;
Secondaryfile();
Secondaryfile(int);
int getX();
static int add1(int);
};
#endif
And the CMakeLists.txt for the project(made in CLion):
cmake_minimum_required(VERSION 3.17)
project(secfile)
set(CMAKE_CXX_STANDARD 14)
include_directories(.)
add_executable(secfile
Mainfile.cpp
Mainfile.h
Mainfile2.cpp
Mainfile2.h
Secondaryfile.cpp
Secondaryfile.h)
After building the project with cmake, you can run it. After doing that, it outputs the following lines:
Hello World!
--------
Value = 12
As expected.
1 https://en.cppreference.com/w/cpp/language/main_function
In C++, I am trying to put two classes in separate files into the same namespace.
I get two errors in main saying that the class Head is not in the namespace Names, and that days is not declared in this scope.
It seems that when I switch the order of the #include statements, the class that doesn't work flip flops between the two. From what I've read, the namespace should open again when the second file is included, and put the second class into the namespace, but it isn't working.
Why does the order of which one I include matter as to which works? What can I do to make both classes be a part of the same namespace, while keeping them in separate header files?
main.cpp
#include <iostream>
#include "dy.hpp"
#include "dayyear.hpp"
int main(){
int d=2;
int y=5;
Names::Dy yup(y,d);
Names::Head days(y,d);
days.print();
yup.print();
return 0;
}
dayyear.hpp
#ifndef DY_H
#define DY_H
namespace Names{
class Head{
int year;
int day;
public:
Head();
Head(int y, int d);
void print();
void change(int y, int d);
};
}
#endif
dayyear.cpp
#include <iostream>
#include "dayyear.hpp"
Names::Head::Head(){
day=0;
year=0;
}
Names::Head::Head(int y, int d){
day=d;
year=y;
}
void Names::Head::print(){
std::cout<<day<<", "<<year<<std::endl;
}
void Names::Head::change(int y, int d){
year=y;
day=d;
}
dy.hpp
#ifndef DY_H
#define DY_H
namespace Names{
class Dy{
int year;
int day;
public:
Dy();
Dy(int y, int d);
void print();
void change(int y, int d);
};
}
#endif
dy.cpp
#include <iostream>
#include "dy.hpp"
Names::Dy::Dy(){
day=0;
year=0;
}
Names::Dy::Dy(int y, int d){
day=d;
year=y;
}
void Names::Dy::print(){
std::cout<<day<<", "<<year<<std::endl;
}
void Names::Dy::change(int y, int d){
year=y;
day=d;
}
That is because both dayyear.hpp and dy.hpp have:
#ifndef DY_H
#define DY_H
.....
#endif
dayyear.hpp should have:
#ifndef DAYYEAR_H
#define DAYYEAR_H
.....
#endif
The preprocessor only regards the first appearance of the same #infdef/#define/#endif construct, all the subsequent ones are replaced with empty code. That is why the order of #include statements matters.
I'm still a noobie in c++ so I am not to skilled in debugging yet. Just trying to figure out how to fix this compilation error.
CruiseShip.cpp:11: error: expected ā)ā before ānā
CruiseShip.cpp
#include "CruiseShip.h"
#include "Ship.h"
#include <iostream>
using namespace std;
Ship s;
int passengers;
CruiseShip(string n, string y, int p) : Ship(n,y)
{
passengers=p;
}
void print()
{
cout<<"Name: "<<s.getName()<<"\nMaximum passengers:"<<passengers<<endl;
cout<<"-------------------------"<<endl;
}
CruiseShip.h
#ifndef CRUISESHIP_H
#define CRUISESHIP_H
#include "Ship.h"
#include <string>
using namespace std;
//class Ship;
class CruiseShip:public Ship{
private:
int passengers;
Ship::Ship s;
public:
CruiseShip(string, string, int);
virtual void print();
};
#endif
Ship.h
#ifndef SHIP_H
#define SHIP_H
#include <string>
using namespace std;
class Ship{
private:
string name;
string built;
public:
Ship();
Ship(string, string);
string getName();
string getBuilt();
virtual void print();
};
#endif
You have 3 errors:
1 and 2. You don't declare print and CruiseShip (The constructor) as part of the class CruiseShip when you define them. You need to:
CruiseShip::CruiseShip(string n, string y, int p) : Ship(n,y) {
virtual void CruiseShip::print() {
3, you dont have a namespace Ship so this is unnecessary:
Ship::Ship s; // This only needs to be Ship s <- NameSpace::ObjectType nameOfObject;
After this it will compile http://ideone.com/wJ6mPO. It will not link however, because you have undefined references to all of the functions you have yet to define.
I want to know how to use members from other files in main c++ code file?
I already know that we can put our declarations in header files.
Let me summarize my current knowledge and missing parts:
Example 1 - using a function from another file
other.cpp
int Add(int a,int b)
{
return a+b;
}
main.cpp
int Add(int,int); //the most important part
int main()
{
Add(12,2);
}
Example 2 - using a global variable from another file
other.cpp
int something=12;
main.cpp
extern int something; //the most important part
int main()
{
cout << something;
}
Question 1 - create an object from a class in another file???
other.cpp
class Rectangle
{
public:
int width;
int height;
int area() { return height*width }
};
main.cpp
int main()
{
Rectangle a; //gives me error,what should i do?
}
You should start using header files. Typically you would have
Rectangle.h a header file with the declarations
class Rectangle{
public:
Rectangle();
Rectangle(int x, int y);
int width;
int height;
int area();
};
Rectangle.cpp Then you'd have a corresponding cpp file with the definitions
#include "Rectangle.h"
Rectangle::Rectangle()
{
width = 0;
height = 0;
}
Rectangle::Rectangle(int x, int y)
{
width = x;
height = y;
}
Rectangle::area()
{
return height*width;
}
Now in your main.cpp
#include "Rectangle.h"
int main()
{
Rectangle a;
}
You need to declare a class Rectangle in main.cpp, preferably using a header file, ex:
other.h
class Rectangle
{ public:int width; int height; int area(); };
other.cpp
#include other.h
int Rectangle::area() { return height*width; }
main.cpp
#include "other.h"
int main()
{
Rectangle a; //gives me error,what should i do?
}
Following your pattern, it should be simply class Rectangle; (forward declaration).
However, you really should consider to create a Rectangle.h and Rectangle.[C|cpp|cc] (any of them), and include the header instead of forward declaring.
The header should contain the declaration, the source the definition.
Place the declaration of the class in a header file. The definition is usually placed in a source file which uses #include to reference the declaration header. Any other source file which require usage of the class will then simply #include the class declaration header.
This might be an easy question, but I cannot figure out why the compiler it's giving me this error. I have two classes. Agent and Environment. WHen I try to add an object of type Agent in my Environment class I get Agent does not name to a type error. I am including Agent.h in my Environment.h class
#ifndef AGENT_H_INCLUDED
#define AGENT_H_INCLUDED
#include <vector>
#include <iostream>
#include "Environment.h"
using namespace std;
class Agent{
public:
Agent(bool s);
vector<int> getPercept();
void setPercept(vector<int> p);
void goForward();
void turnRight();
void turnLeft();
void clean();
void paint();
void refuel();
bool needsRefuel();
void turnOn();
void turnOff();
bool isActive();
void move();
int getCurX();
int getCurY();
char getCurDir();
void setCurrentPosition(int x, int y, char d);
private:
vector<int> percept;
int actions;
int performance;
char direction;
bool isOn;
int curX;
int curY;
char curDir;
};
#endif // AGENT_H_INCLUDED
/*************************/
#ifndef ENVIRONMENT_H_INCLUDED
#define ENVIRONMENT_H_INCLUDED
#include <vector>
#include <iostream>
#include "Agent.h"
using namespace std;
class Environment{
public:
Environment(vector<vector<char> > roomData);
Environment(vector<vector<char> > roomData, vector<int> status);
void setRoomData(vector<vector<char> > roomData);
bool isSimulationComplete();
void isAgentHome();
vector<int> sendLocationStatus();
void printEnvironment();
void setAgentHome(int x, int y);
vector<int> getAgentPercept();
void setAgentPercept(vector<int> status);
void setAgentPosition(int x, int y, char p);
vector<int> sendAgentPercept();
void calculateAgentPercept();
private:
vector<vector<char> > room;
vector<int> agentPercept;
bool simulationComplete;
int agentHomeX;
int agentHomeY;
int agentX;
int agentY;
char agentDir;
Agent agent; ////ERROR IS HERE
};
#endif // ENVIRONMENT_H_INCLUDED
Your agent.h includes environment.h. The agent.h file is parsed in order from top to bottom, so when environment.h is parsed, the compiler doesn't know what an Agent is. There appears to be no reason to incude environment.h in agent.h.
Apart from what the comments already said, you can't have two header files include each other. There is no reason for Agent.h to include Environment.h, so if a .cpp file includes Agent.h first, it'll fail (since it will first go through Environment.h, which requires Agent).
IF you have a situation where two header files depend on each other's definitions, use forward declarations where you can, or split your header files up into more header files.