-1

I have a problem with redefinition I tried #pragma once and #ifndf statements but none of these worked for me. My main.cpp


#include <iostream>
#include "kolo.h"
#include "prostokat.h"
#include "trojkat.h"
using namespace std;
//overloading
void zmienno(float x)
{
    cout<<x;
}
void zmienno(int x)
{
    cout<<x;
}
int main()
{
    //tworzenie obiektu zmienna lokalna
    Kolo kolo(5);
    Trojkat trojkat(1,2,3);
    Prostokat prostokat(1,2);
    //wskaznik
    Kolo * wskkolo = new Kolo(5);
    Trojkat * wsktrojkat = new Trojkat(1,2,3);
    Prostokat * wskprostokat = new Prostokat(1,2);
    //konstruktory zaprezentowane wyżej, metody np:
    double pole = kolo.Pole(); //pole kola
    double obwod = wsktrojkat->Obwod(); //obwod trojkata
    kolo.SetR(3);
    pole = kolo.Pole(); // inne pole po zmiane R
    FiguraPlaska *wsk[3];
    wsk[0]=wskkolo;
    wsk[1]=wskprostokat;
    wsk[2]=wsktrojkat;
    for(int i=0;i<3;i++)
    {
        cout<<wsk[i]->Pole()<<endl;//metody wirtualne
    }
    wskprostokat->~Prostokat();
    wskkolo->~Kolo();
    wsktrojkat->~Trojkat();
    // overriding -> polimorfizm metody pole, obwod
    // overloading: funkcje w linii nr8
    zmienno(2);
    //ta sama nazwa funkcji, rozszerzona o inne typy argumentow
    delete[]wsk;
    delete wskkolo,wskprostokat,wsktrojkat;



    return 0;
}

and one of my header files as the structure in every file is the same, including figuraplaska.h


#pragma once
#include "figuraplaska.h"

class Prostokat : public FiguraPlaska {
private:
 double a,b;
protected:
 void Wypisz(std::ostream& out) const override;
public:
 Prostokat(double a, double b);
 double GetA() const;
 void SetA(double a);
 double GetB() const;
 void SetB(double b);
 double Obwod() override;
 double Pole() override;

 ~Prostokat() override;
};

and figuraplaska.h



#include <iostream>
using namespace std;

class FiguraPlaska {
protected:
 virtual void Wypisz(std::ostream& out) const = 0;
 friend std::ostream& operator<<(std::ostream& os, const FiguraPlaska& figura);
public:
 virtual double Pole() = 0;
 virtual double Obwod() = 0;
 virtual ~FiguraPlaska();
};

Errors are


    [Running] cd "/home/bj/Pulpit/PO1/" && g++ main.cpp -o main && "/home/bj/Pulpit/PO1/"main
In file included from prostokat.h:2:0,
                 from main.cpp:3:
figuraplaska.h:5:7: error: redefinition of ‘class FiguraPlaska’
 class FiguraPlaska {
       ^~~~~~~~~~~~
In file included from kolo.h:2:0,
                 from main.cpp:2:
figuraplaska.h:5:7: note: previous definition of ‘class FiguraPlaska’
 class FiguraPlaska {
       ^~~~~~~~~~~~
In file included from trojkat.h:2:0,
                 from main.cpp:4:
figuraplaska.h:5:7: error: redefinition of ‘class FiguraPlaska’
 class FiguraPlaska {
       ^~~~~~~~~~~~
In file included from kolo.h:2:0,
                 from main.cpp:2:
figuraplaska.h:5:7: note: previous definition of ‘class FiguraPlaska’
 class FiguraPlaska {
       ^~~~~~~~~~~~
main.cpp: In function ‘int main()’:
main.cpp:45:13: warning: deleting array ‘wsk’
     delete[]wsk;
             ^~~

[Done] exited with code=1 in 2.043 seconds


I have no clue how can I repair it, any suggestions? None of help in the internet worked for me :/

1 Answers1

3

at begininnging of figuraplaska.h add something like

#ifndef FIGURAPLASKA_H_
#define FIGURAPLASKA_H_

and at the end add

#endif

doing that your file content will not be included two times in each source file

Do something similar for other header files (of course using a different macro)


so figuraplaska.h becomes for instance

#ifndef FIGURAPLASKA_H_
#define FIGURAPLASKA_H_

#include <iostream>
using namespace std;

class FiguraPlaska {
protected:
 virtual void Wypisz(std::ostream& out) const = 0;
 friend std::ostream& operator<<(std::ostream& os, const FiguraPlaska& figura);
public:
 virtual double Pole() = 0;
 virtual double Obwod() = 0;
 virtual ~FiguraPlaska();
};

#endif

Out of that as said in a remark you have a problem in the line

delete wskkolo, wskprostokat, wsktrojkat;

because only wsktrojkat is deleted : the value of a coma separated expression is the value of the last expression

replace this line by

delete wskkolo;
delete wskprostokat;
delate wsktrojkat;

An other problem is you have these lines before :

wskprostokat->~Prostokat();
wskkolo->~Kolo();
wsktrojkat->~Trojkat();

remove them, when doing delete wskprostokat that will apply ~Prostokat etc

And also remove the line

delete[]wsk;

because wsk is placed in the stack, it is not allocated in the heap :

FiguraPlaska *wsk[3];
bruno
  • 32,421
  • 7
  • 25
  • 37
  • so you mean #endif at the end of the whole code or at the end of defining header files – Bartek Juśkiewicz Mar 29 '20 at 13:33
  • 1
    @BartekJuśkiewicz At the beginning and end of **every** header file. Or you could put `#pragma once` at the beginning of **every** header file. – john Mar 29 '20 at 13:34
  • @BartekJuśkiewicz the *#endif* finishes the *#ifndef* so of course it is at the end of the header file – bruno Mar 29 '20 at 13:34
  • @john I did it but it didn't help with this problem – Bartek Juśkiewicz Mar 29 '20 at 13:40
  • then my last question as I had never used this before, "FIGURAPLASKA_H_" is the general rule to write after the "ifndf" and "define" statement? With capital letters and then _ extension _ ? – Bartek Juśkiewicz Mar 29 '20 at 13:41
  • @BartekJuśkiewicz to reuse the name of the file allows to have a unique name, and to use capitalized is not mandatory but a convention followed each time one define a macro to not risk to have a synonymous with something else. I am pretty sure you did a mistake and do not follow my proposal if you have the same result. Is your problem still for *FiguraPlaska* ? if not that means you forgot to make the same for your other headers – bruno Mar 29 '20 at 13:44
  • i replied to john that didn't work for me #pragma once :) i will try your solution now – Bartek Juśkiewicz Mar 29 '20 at 13:46
  • @BartekJuśkiewicz Either `#pragma once` or `#ifndef` are the solution to this problem. If they don't work for you it is because you are doing something wrong. – john Mar 29 '20 at 14:12
  • g++ -o main.cpp prostokat.cpp kolo.cpp trojkat.cpp figuraplaska.cpp /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status any idea how should i launch it with the console? Now it somehow deletes my main file and throw an error? – Bartek Juśkiewicz Mar 29 '20 at 14:21
  • `g++ -o main.cpp ...` That's a serious mistake, you are asking the compiler to call your program main.cpp, not asking it to compile main.cpp. It should be `g++ -o something main.cpp ...`. Then you program will be called something, and main.cpp will be compiled. – john Mar 29 '20 at 15:14
  • @john oh yes I did not see, he had a bad idea doing *-o main.cpp* – bruno Mar 29 '20 at 15:17