I just got into C++ and I was trying to write a simple code for a simulation, but I bumped into a multiple definition problem than I cannot solve.
So, I'm creating a class and this is the header file:
Piano.h
#ifndef PIANO_H
#define PIANO_H
#include"vettore.h"
#include"PuntoMat.h"
#include<string>
#include<vector>
class Piano
{
public:
//Costruttori
Piano(std::string material, float lenght, float inclin = 0)
: m_material(material), m_lenght(lenght), m_inclin(inclin), m_time(0) {;}
//Metodo per l'aggiunta di corpi al piano
void Add(PuntoMat p) { m_corpi.push_back(&p); }
//Metodo che stampa le coordinate dei corpi nel sistema
void Print();
private:
std::string m_material;
std::vector<PuntoMat*> m_corpi;
float m_lenght;
float m_inclin;
float m_time;
};
#endif
this is the corresponding file .cxx, where I define the function "Print"
Piano.cxx
#include"vettore.h"
#include"PuntoMat.h"
#include"Piano.h"
#include<iostream>
#include<stdlib.h>
#include<vector>
void Piano::Print()
{ std::cout << "Tempo: " << m_time << " s" << std::endl;
if(m_corpi.size() == 0)
{ std::cout << "Nessun corpo sul piano" << std::endl;
exit(1);
}
for(int i=0; i<m_corpi.size(); i++)
{ std::cout << *m_corpi[i] << std::endl;
}
std::cout << std::endl;
}
This is the code I'm using to validate the class
main.cxx
#include<iostream>
#include"vettore.h"
#include"PuntoMat.h"
#include"Piano.cxx"
#include<string>
main()
{
PuntoMat a(3, Vettore( 0, 0), Vettore( 5.4, 0), "Legno");
PuntoMat b(5, Vettore( 8.3, 6.5), Vettore( 0, 0), "Vetro");
Piano p( "Ferro", 50);
p.Add(a);
p.Add(b);
p.Print();
return 0;
}
When I compile I get a multiple definition error about the function Print, this one:
/tmp/ccp1giKM.o: In function `Piano::Stampa()':
main.cxx:(.text+0x0): multiple definition of `Piano::Stampa()'
/tmp/cctCJRQF.o:Piano.cxx:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
I really don't know how to solve this problem, since it seems to me that the function Print() has been defined only in the file Piano.cxx. Can anyone help me with this?
P.s. Ignore the general meaning of the code and the comments (they are in italian). All the other classes included have been already validate and there is no problem with them.
Your problem is that you try to include the cxx file. You should only include .h/.hpp files. Instead of include the source files you should tell your compiler to use it.
So in your case removing the "#include"Piano.cxx" line and than calling your compiler in this way(asuming g++),
g++ main.cxx Piano.cxx
should fix the problem. If you want to create bigger projects you should have a look at creating object files from your sources.
Related
Ok, so I just installed Visual Studio yesterday and was just minding my own business trying to make a learn C++/wasting time. I ran the code you're about to see a few times without issue and then I included the StlLock.h file, then I happened upon this error list.
Error list in my Visual Studio along with the "problematic" code, I guess.
The errors vanish as soon as I remove StlLock.h.
As far as I recall I did not touch StlLock.h at all. Is there just something wrong with it?
Also, I'm pretty new to programming and C++. I'm trying to teach myself but got caught up in this.
The full code is in 2 files:
ABLASAN.cpp
#include "ABLASAN.h"
int main()
{
Math test;
test.Show_Atributes();
test.radijus = 4;
std::cout << test.Area(test.radijus) << "\n";
std::cin.get();
}
ABLASAN.h
#pragma once
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <StlLock.h>
#include <cmath>
constexpr double PI = 3.14159265358979323846;
class Math{
public:
double radijus, x_os, y_os;
Math(){
x_os = 0;
y_os = 0;
radijus = 0;
}
double Area(double x, double y)
{
return x * y;
}
double Area(double r)
{
return pow(r, 2) * PI;
}
void Show_Atributes() {
std::cout << "X-os: " << x_os << "\nY-os: " << y_os << "\nRadijus: " << radijus << std::endl;
}
};
P.S.
Just as a side-note: I used the cmath file and read somewhere that that file has defined mathematical constants using this:
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
int main() {
std::cout << M_PI << " " << M_E << " " << M_SQRT2 << endl;
return 0;
}
I can't seem to get that to work.
I'm using the Visual Studio C++20 compiler just in case it's important. Also, I did not change any project settings/properties/anything.
Thanks to everyone and anyone in advance.
Also, I'm deeply sorry if this was already answered somewhere. I just didn't find it before writing this up.
This question already has answers here:
Separating class code into a header and cpp file
(8 answers)
Closed 1 year ago.
I have to create a C++ program with a header file, implementation file, and test file for the class "Rectangle." However, I am unsure how to properly separate the header class, and I figure that's why I'm encountering errors in my test class. I am using the IDE codelite for this assignment.
Here is my header file:
#ifndef RECTANGLE_H
#define RECTANGLE_H
class rectangle {
private:
double width;
double height;
public:
rectangle();
rectangle(double inputWidth, double inputHeight);
double getWidth();
double getHeight();
double getArea();
double getPerimeter();
void printRectangle(string objectName);
}
#endif
I am getting an error message on the line that declares the class, which says, "Expected ';' after top level declarator."
I do not have any errors showing in my .cpp implementation file, but I am getting numerous in my tester file. It is not recognizing that I'm trying to create objects of the rectangle class, or at least it isn't when I try to call the parameterized constructor. When I do, it's giving me an error of "use of undeclared identifier 'rectangle'," then on the object that is supposed to take parameters, it is asking if I meant to type the original, default object.
Here is the code of the beginning of the file and the (attempted) creation of objects:
#include <stdio.h>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include "rectangle.h"
#include "rectangle.cpp"
using namespace std;
int main() {
double inputWidth;
double inputHeight;
rectangle myRectangle;
cout << "Enter the width of the rectangle:" << endl;
cin >> inputWidth;
cout << "Enter the height of the rectangle:" << endl;
cin >> inputHeight;
rectangle herRectangle(inputWidth, inputHeight);
Then, I am getting an error on every line of code that tries to call a method for the object created using the parameterized constructor, saying "use of undeclared identifier 'herRectangle.'" For some reason I am not getting these error messages on the lines of code for the default rectangle.
Here is the code showing the method calls for the 'herRectangle' object:
cout << "herRectangle" << endl;
cout << "------------" << endl;
cout << "Width: " << herRectangle.getWidth() << endl;
cout << "Height: " << herRectangle.getHeight() << endl;
cout << "Area: " << herRectangle.getArea() << endl;
cout << "Perimeter: " << herRectangle.getPerimeter() << endl;
herRectangle.printRectangle();
Any and all help would be greatly appreciated! If there's anything else you would like for me to show in order to help, please just let me know. Sorry if my formatting is a bit wonky as well, I'm new to the forum.
It is simple. First you define your header file .h or .hpp.
Rectangle.hpp
#ifndef RECTANGLE_H
#define RECTANGLE_H
class Rectangle{
//Method declaration
}; // Notice samicolon
#endif
Rectangle.cpp
#include "Rectangle.hpp"
// Method implementation
and then in main.cpp
#include "Rectangle.hpp"
int main{
Rectangle rect;
}
This is how you separate you Definitions and implementations.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I have to refactor a project and thought of separating the sources and header files. It worked great for the "Empregado" class, but when I tried to replicate it to the "Engenheiro" class I got the multiple declaration error
A screenshot of the error I'm getting when trying to build the project
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj): In function `ZNK10Engenheiro7getNomeB5cxx11Ev':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:5: multiple definition of `Engenheiro::getNome[abi:cxx11]() const'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Engenheiro.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:5: first defined here
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj): In function `ZN10Engenheiro7setNomeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:9: multiple definition of `Engenheiro::setNome(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Engenheiro.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:9: first defined here
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj): In function `ZNK10Engenheiro11getProjetosEv':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:13: multiple definition of `Engenheiro::getProjetos() const'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Engenheiro.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:13: first defined here
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj): In function `ZN10Engenheiro11setProjetosEi':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:17: multiple definition of `Engenheiro::setProjetos(int)'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Engenheiro.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Engenheiro.cpp:17: first defined here
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Vendedor.cpp.obj): In function `ZN8Vendedor7setNomeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Vendedor.cpp:5: multiple definition of `Vendedor::setNome(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Vendedor.cpp:5: first defined here
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Vendedor.cpp.obj): In function `ZNK8Vendedor7getNomeB5cxx11Ev':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Vendedor.cpp:9: multiple definition of `Vendedor::getNome[abi:cxx11]() const'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Vendedor.cpp:9: first defined here
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(Vendedor.cpp.obj): In function `ZN8Vendedor15quotaTotalAnualEv':
D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Vendedor.cpp:13: multiple definition of `Vendedor::quotaTotalAnual()'
CMakeFiles\exercicio_revisao_refatoracao.dir/objects.a(main.cpp.obj):D:/UFMG/UFMG-DCC204/CPP/Modulo3/exercicio-revisao-refatoracao/Vendedor.cpp:13: first defined here
collect2.exe: error: ld returned 1 exit status
I have uploaded all the files to GitHub https://github.com/jvbraganca/exercicio-revisao-refatoracao/tree/multiple-declaration-error
The header and source file for Engenheiro are here:
Engenheiro.h
#ifndef ENGENHEIRO_H
#define ENGENHEIRO_H
#include <string>
#include "Empregado.h"
class Engenheiro : public Empregado {
public:
const std::string &getNome() const;
void setNome(const std::string &nome);
int getProjetos() const;
void setProjetos(int projetos);
private:
std::string nome;
int projetos;
};
#endif //ENGENHEIRO_H
Engenheiro.cpp
#include "Empregado.h"
void Empregado::setHorasTrabalhadas(double horasTrabalhadas) {
Empregado::horasTrabalhadas = horasTrabalhadas;
}
void Empregado::setSalarioHora(double salarioHora) {
Empregado::salarioHora = salarioHora;
}
void Empregado::setQuotaMensalVendas(double quotaMensalVendas) {
Empregado::quotaMensalVendas = quotaMensalVendas;
}
double Empregado::getHorasTrabalhadas() const {
return horasTrabalhadas;
}
double Empregado::getSalarioHora() const {
return salarioHora;
}
double Empregado::getQuotaMensalVendas() const {
return quotaMensalVendas;
}
double Empregado::getPagamentoMes() const {
double horasTrabalhadas = getHorasTrabalhadas();
/**
* Calcula as horas extras trabalhadas, bônus de 50% se
* tiver mais que 8 horas extras trabalhadas.
*/
if (horasTrabalhadas > MAX_HORAS_TRABALHADAS) {
double x = horasTrabalhadas - MAX_HORAS_TRABALHADAS;
horasTrabalhadas += x / 2;
}
return horasTrabalhadas * salarioHora;
}
void Empregado::printInfo(const std::string &nome, double salario, int projetosOuQuota, int tipoFuncionario) {
if (tipoFuncionario == 1) {
std::cout << "Nome: " << nome << std::endl;
std::cout << "Salario Mes: " << salario << std::endl;
std::cout << "Projetos: " << projetosOuQuota << std::endl;
std::cout << std::endl;
} else if (tipoFuncionario == 2) {
std::cout << "Nome: " << nome << std::endl;
std::cout << "Salario Mes: " << salario << std::endl;
std::cout << "Quota vendas: " << projetosOuQuota << std::endl;
std::cout << std::endl;
} else {
throw "Tipo de funcionário não reconhecido!";
}
}
Empregado::~Empregado() = default;
I can't see where I am declaring it multiple times. Maybe it is a dummy question
Any help is welcome, thanks!
Solved: I was importing the source file instead of the header file on main.cpp
As was mentioned in main.cpp you are including source files.
#include "Engenheiro.cpp"
#include "Vendedor.cpp"
You should include the corresponding header files instead.
#include "Engenheiro.h"
#include "Vendedor.h
This fixes the problem:
1>------ Rebuild All started: Project: ZERO_CHECK, Configuration: Debug x64 ------
1>Checking Build System
2>------ Rebuild All started: Project: exercicio_revisao_refatoracao, Configuration: Debug x64 ------
2>Building Custom Rule C:/Users/juanr/Downloads/exercicio-revisao-refatoracao/CMakeLists.txt
2>Empregado.cpp
2>Engenheiro.cpp
2>main.cpp
2>Vendedor.cpp
2>Generating Code...
2>exercicio_revisao_refatoracao.vcxproj -> C:\Users\juanr\Downloads\exercicio-revisao-refatoracao\build\Debug\exercicio_revisao_refatoracao.exe
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========
I just started using Microsoft Visual Studio 2010 for compiling my C++ code.
I have a project that is linked to another project called firmlib. To that end, I have linked the header files and libraries as described here:
http://www.steptools.com/support/stdev_docs/help/settings_vc10.html#header
In the new main that I wrote I call a method called readFromFile of the class Curve, as follows:
#include "stdafx.h"
#include <iostream>
#include "curve.h"
int _tmain(int argc, _TCHAR* argv[])
{
unsigned long n;
Curve discountCurve;
discountCurve.readCurve("fileName");
std::cout << "Give a natural number: " << endl;
std::cin >> n;
std::cout << "The faculty of " << n << " equals " << faculty(n) << ".\n";
return 0;
}
referring to the following method declaration (in Curve.h)
void readCurve(const char * filename){}
and implementation (in Curve.cpp) (I deleted some parts that are irrelevant for this post):
void Curve::readCurve(const char * filename){
cout << "Hi. This is the function Curve::readCurveat work.") << endl;
ifstream data;
marketData.open(filename);
marketData.close;
}
I built in the stream to the console in order to make sure that the source code is actually compiled. However, nothing is happening! So apparently the source code is not compiled.
Can anyone tell me what is going wrong here? I am puzzled ...
Thanks!
I've already wasted time trying to figure this out but no luck so far...I've tried looking through StackOverflow for the same problem but mostly it's related to the IDE people are using, such as VS or Eclipse.
I was doing some examples from the Stanford Reader for their C++ course but the code won't work right. I'm trying to figure out how to use external libraries but something keeps going wrong. I'm probably not using the right command but then I don't know which command to use.
I'm using Cygwin and it's terminal to do the c++ exercises. I have all the files in the same folder. I am using windows 7 but that shouldn't be the biggest problem though.
As an example this error shows well what I get when writing g++ Craps.cpp:
$ g++ Craps.cpp
/tmp/ccdTdi0t.o:Craps.cpp:(.text+0x1cf): undefined reference to `randomInteger(int, int)'
/tmp/ccdTdi0t.o:Craps.cpp:(.text+0x1e6): undefined reference to `randomInteger(int, int)'
/usr/lib/gcc/i686-pc-cygwin/4.5.3/../../../../i686-pc-cygwin/bin/ld: /tmp/ccdTdi0t.o: bad
reloc address 0x0 in section `.ctors'
collect2: ld returned 1 exit status
The example I was running this time is just one of the ones with external libraries which gives me the same kind of error if I wrong the other. It won't find the library.
This is my main also called Craps.cpp:
#include <iostream>
#include "random.h"
using namespace std;
bool tryToMakePoint(int point);
int rollTwoDice();
int main() {
cout << "This program plays a game of craps." << endl;
int point = rollTwoDice();
switch (point) {
case 7: case 11:
cout << "That's a natural. You win." << endl;
break;
case 2: case 3: case 12:
cout << "That's craps. You lose" << endl;
break;
default:
cout << "Your point is " << point << "." << endl;
if (tryToMakePoint(point)) {
cout << "You made your point. You win." << endl;
} else {
cout << "You rolled a seven. You lose." << endl;
}
}
return 0;
}
bool tryToMakePoint(int point) {
while (true) {
int total = rollTwoDice();
if (total == point) return true;
if (total == 7) return false;
}
}
int rollTwoDice() {
cout << "Rolling the dice . . . " << endl;
int d1 = randomInteger(1, 6);
int d2 = randomInteger(1, 6);
int total = d1 + d2;
cout << "You rolled " << d1 << " and " << d2
<< " - that's " << total << endl;
return total;
}
My random.cpp:
#include <cstdlib>
#include <cmath>
#include <ctime>
#include "random.h"
using namespace std;
void initRandomSeed();
int randomInteger(int low, int high) {
initRandomSeed();
double d = rand() / (double(RAND_MAX) + 1);
double s = d * (double(high) - low + 1);
return int(floor(low + s ));
}
double randomReal(double low, double high) {
initRandomSeed();
double d = rand() / (double(RAND_MAX) + 1);
double s = d * (high - low);
return low + s;
}
bool randomChance(double p) {
initRandomSeed();
return randomReal(0, 1) < p;
}
void setRandomSeed(int seed) {
initRandomSeed();
srand(seed);
}
void initRandomSeed() {
static bool initialized = false;
if (!initialized) {
srand(int(time(NULL)));
initialized = true;
}
}
and lastly my random.h:
#ifndef _random_h
#define _random_h
int randomInteger(int low, int high);
double randomReal(double low, double high);
bool randomChance(double p);
void setRandomSeed(int seed);
#endif
I hope someone can help me. If it's the Cygwin command that's wrong it would be great if I could see what I should write.
Edit:
Just found out that I couldn't even write down the examples in the book right. Fixed now and should be without mistakes...I dearly hope so. Sorry about that.
Shortly, you should add random.cpp (or, if you already compiled it, an object file or a library where its compiled code resides) into your command line:
g++ Craps.cpp random.cpp
The problem you face is that the command line says the code in Craps.cpp should be compiled and then linked into an executable. While it's sufficient to have forward declarations of external functions to compile the file, you should provide the code of these functions to the linker for it to be able to create an executable.
As for libraries, you usually specify ones that you need to use with -l option to GCC. And you might need to specify (with -L) the path where to take libraries from, even if they all are in the current directory. E.g. provided that you have a library called librandom.a or librandom.so in the current directory:
g++ Craps.cpp -L. -l random
For external libraries, other directories may need to be specified so that the linker knows where to find the libraries it needs.
Other answer has the simple command to compile this, but here's a very rough and simple Makefile example, to get you started down that road. Create a file named Makefile with these contents, where <tab> must be an actual tab character, not some number of spaces:
Craps.exe : Craps.o random.o
<tab>g++ -o $# $^
Craps.o random.o : random.h
Then just run
make Craps.exe
(possibly gmake or mingw32-make instead of plain make).
Now Make has some magic built in about file types, so when it sees Craps.exe needs those two .o files, it'll start looking for files it could make them from, and it finds .cpp files, and knows how to compile them into .o files. Now it doesn't implicitly know how make .exe out of .o files, so that's why we have the 2nd line. There $# means the target of the rule (Craps.exe here), while $^ means all the files listed after the :.
The Craps.o random.o:random.h rule means, that if random.h is changed, Craps.o and random.o needs to be re-created again (these .h file dependencies can be generated automatically, but as long as you have just a few files, writing them by hand is ok).
If you need to add more source files, just add them with the .o suffix to the first line, and make will include them in the compilation. Also note how make will only compile changed files... Then you will need to add .h file dependencies when you get more .h files.