Pomoc w zadaniu - nagłówki i moduły C++

0

Cześć
Mam problem z zadaniem w C++. Mam podzielić program na plik nagłówkowy i modułowy, plik nagłowkowy to nie problem natomiast coś jest nie tak z plikem z modułami (otrzymuje blad
Build: Debug in spr3 (compiler: GNU GCC Compiler) ===|
error: expected initializer before '::' token
.

Kod:
Main.cpp

#include <iostream>
#include "naglowek.h"
using namespace std;
int main()
{
    cout <<"Witaj!" << endl;
    Punkt1 punkt1;
    Punkt2 punkt2;
    return 0;
}

Naglowek.h

#include <algorithm>
#include <string>
using namespace std;


class Punkt1
{
    int p1;
    int p2;
    void wyswietl();

public:
    Punkt1();
};

Punkt1::Punkt1()
{


    cout << " Domyslne wspolrzedne punktu to:" << endl;
    cout << p1 <<endl;
    cout << p2 << endl;

    p1 = 5;
    p2 = 4;

    cout <<"Wspolrzedne ustalone to: " <<endl;
   void wyswietl();

   

}

//postac 2/////////////////////////////////////////////////////////
class Punkt2
{
    int p1;
    int p2;

public:
    Punkt2();
};

Punkt2::Punkt2()
: p1 (2),
p2 (4)
    {
    cout <<"Wspolrzedne ustalone w drugim konstruktorze to: " <<endl;
    cout << p1 <<endl;
    cout << p2 << endl;



    }

moduly.cpp


#include <iostream>
#include "naglowek.h"
using namespace std;

void Punkt1()::wyswietl()
{
    cout << p1 <<endl;
    cout << p2 << endl;

}

Czy ktoś podpowie co jest nie tak ?

2

Obstawiam, że to void Punkt1()::wyswietl() (popatrz, gdzie masz ())

2

Uważaj na terminologię. Jak napisałeś o modułach, to przez chwilę byłem przekonany, że eksperymentujesz z modułami z C++20 (na razie niewiele kompilatorów to wspiera).

0

@MarekR22: Przepraszam, wykładowca chyba trochę namieszał w poleceniu zadania :)
@alagner Nie bardzo rozumiem, tutaj odwołuje się do klasy Punkt1 a nastepnie do jej metody wyswietl (chyba ,że coś pomyliłem). Co jest nie tak z nawiasami ?

1

void Punkt1()::wyswietl() << jest
void Punkt1::wyswietl() << powinno być

0

Dziękuję za wskazówki, teraz jednak mam inny błąd:

naglowek.h|19|multiple definition of `Punkt1::Punkt1()'|

Z tego co rozumiem to gdzieś coś jest podwójnie zdefiniowane, problem w tym ,że usunąłem jedynie nawias

 void Punkt1::wyswietl()
0

W konstruktorze Punkt1 na końcu. BTW, nie używaj using namespace w headerach.
EDIT: kompilator Ci w sumie powiedział gdzie jest błąd. Pisz to w dobrym edytorze to sam zobaczysz.
EDIT2: sorry, coś mnie zaćmiło, @kq napisał dobrze.
Ale w Punkt1() pod koniec tak czy siak masz dodatkowe void wyswietl();

1

Problemem jest definicja funkcji (nie-inline) w nagłówku. include działa na zasadzie kopiuj-wklej zawartości pliku, więc w każdym pliku bezpośrednio lub pośrednio zawierającym naglowek.h masz definicję funkcji Punkt1::Punkt1(), przez co masz wiele jej definicji.

0

Inaczej mówiąc niż @kq ale to samo:

Nie implementuj w nagłówku metod poza klasą.

W klasie by by było OK - wtedy by była nazwa prosta Punkt2() a nie kwalifikowana Punkt2::Punkt2()

0
kq napisał(a):

Problemem jest definicja funkcji (nie-inline) w nagłówku. include działa na zasadzie kopiuj-wklej zawartości pliku, więc w każdym pliku bezpośrednio lub pośrednio zawierającym naglowek.h masz definicję funkcji Punkt1::Punkt1(), przez co masz wiele jej definicji.

Ok, tylko ,że gdy wyrzucę naglowek.h z pliku moduly.cpp mam bład error: 'Punkt1' has not been declared| co jest dla mnie całkowicie zrozumiałe ( skoro nie ma podpiętego pliku naglowkowego). Natomiast gdy wyrzucę go z main.cpp sypię się w ten sam sposób ( co też poniekąd jest zrozumiałe).

Dla jasności dorzucę też treść zadania:

Stosując jeden plik kodu, napisać prosty program prezentujący idee konstruktora i destruktora. Klasa o nazwie Punkt przechowuje współrzędne punktu na płaszczyźnie oraz metodę je ustalającą oraz odczytującą. Pojawia się tu też konstruktor inicjalizujący współrzędne punktu podanymi, podczas tworzenia obiektu, wartościami współrzędnych. Kolejno argumenty konstruktora zasilić wartościami domyślnymi. Omówić tematykę konstruktorów przeciążonych i wartości domyślnych. Utworzyć dwa obiekty używając konstruktorów w różnych postaciach. Omówić słowo kluczowe this na przykładzie inicjalizacji cech obiektu argumentami konstruktora posiadającymi tą samą nazwę jak cechy. Zastanowić się jak tworzone i przechowywane są obiekty. Czy obiekty utworzone tak jak każda inna zmienna są w trakcie pracy kasowane gdy programista ich nie używa?

Zadanie 2a
Powyższy kod podzielić na plik nagłówkowy oraz na plik modułu z kodem metod.

1

error: 'Punkt1' has not been declared|

Wyrzuć definicję, nie deklarację.

Deklaracja - informuje (kompilator), że coś istnieje
Definicja - pełne dane (czyli ciało) funkcji, klasy itd.

0

Teraz coś pokombinowałem i niestety dalej program się nie kompiluje.. Jeśli ktoś spojrzałby gdzie jest błąd będę bardzo wdzięczny, kod poniżej:
Main.cpp

#include <iostream>

#include "naglowek.h"
using namespace std;


int main()
{
    cout <<"Witaj!" << endl;
    Punkt1 punkt1;
    Punkt2 punkt2;
    return 0;
}

naglowek.h

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <string>



class Punkt1
{
    int p1;
    int p2;
    //void wyswietl();

public:
    Punkt1();
};
Punkt1::Punkt1()
{


    std::cout << "Domyslne wspolrzedne punktu to:" << std::endl;
    std::cout << p1 <<std::endl;
    std::cout << p2 << std::endl;

    p1 = 5;
    p2 = 4;

    std::cout <<"Wspolrzedne ustalone to: " <<std::endl;
   void wyswietl();



}

//postac 2/////////////////////////////////////////////////////////
class Punkt2
{
    int p1;
    int p2;

public:
    Punkt2();
};

Punkt2::Punkt2()
: p1 (2),
p2 (4)
    {
    std::cout <<"Wspolrzedne ustalone w drugim konstruktorze to: " <<std::endl;
    std::cout << p1 <<std::endl;
    std::cout << p2 << std::endl;

    

    }

Moduly.cpp

#include <iostream>
#include "naglowek.h"
using namespace std;

void Punkt1::wyswietl()
{

    cout << p1 <<endl;
    cout << p2 << endl;

}

1

Byłoby łatwiej gdybyś podesłał jaki błąd się pojawił. Tak na szybko to na pewno jest błąd w deklaracji funkcji void wyswietl();, powinna być ona w ciele klasy a nie w ciele konstruktora. Czyli w zasadzie trzeba odkomentować to tutaj:

class Punkt1
{
    int p1;
    int p2;
    //void wyswietl();

public:
    Punkt1();
};

i usunąć z konstruktora Punkt1; Domyślam się, że chciałeś użyć tej funkcji w konstruktorze, wtedy po prostu wpisz wyswietl(); zamiast void wyswietl();

0

@Trisolaris: Poprawiłem kod tak jak mówiłeś, teraz otrzymałem bład;
|error: definition of implicitly-declared 'Punkt1::Punkt1()'| w pliku naglowek.h

Odkomentowałem void wyswietl(); a nastepnie zakomentowałem testowo Punkt1();

0

Wyrzuć definicje funkcji z nagłówka.

0
kq napisał(a):

Wyrzuć definicje funkcji z nagłówka.

W którym miejscu ? W nagłówku mam tylko zdefiniowane dwie klasy (Punkt1 i Punkt 2)

0

Masz też definicję konstruktora Punkt1.

0

Usunałem -przeniosłem do main.cpp

class Punkt1
{
    int p1;
    int p2;
    void wyswietl();
public:
   // Punkt1();
};

ale mam kolejny blad:

|10|error: 'Punkt1' does not name a type|

0

Gdzie masz ten błąd?

0

@kq:
W pliku naglowkowym

0

Niespecjalnie chce mi się w to wierzyć. Pokaż cały kod.

0

@kq:
Main.cpp

#include <iostream>
#include "naglowek.h"
using namespace std;
class Punkt1
{
    int p1;
    int p2;
    void wyswietl();

public:
   // Punkt1();
};

int main()
{
    cout <<"Witaj!" << endl;
    Punkt1 punkt1;
    Punkt2 punkt2;
    return 0;
}

naglowek.h

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <string>
/*class Punkt1
{
    int p1;
    int p2;
    void wyswietl();

public:
   // Punkt1();
};
*/
Punkt1::Punkt1()
{


    std::cout << "Domyslne wspolrzedne punktu to:" << std::endl;
    std::cout << p1 <<std::endl;
    std::cout << p2 << std::endl;

    p1 = 5;
    p2 = 4;

    std::cout <<"Wspolrzedne ustalone to: " <<std::endl;
   wyswietl();

    //cout << p1 <<endl;
    //cout << p2 << endl;

    /*cout <<"Podaj pierwsza wspolrzedna:" <<endl;
    cin >> p1;
    cout <<"Podaj druga wspolrzedna:" <<endl;
    cin >> p2;
*/


}

//postac 2/////////////////////////////////////////////////////////
class Punkt2
{
    int p1;
    int p2;

public:
    Punkt2();
};

Punkt2::Punkt2()
: p1 (2),
p2 (4)
    {
    std::cout <<"Wspolrzedne ustalone w drugim konstruktorze to: " <<std::endl;
    std::cout << p1 <<std::endl;
    std::cout << p2 << std::endl;

    /*cout <<"Podaj pierwsza wspolrzedna:" <<endl;
    cin >> p1;
    cout <<"Podaj druga wspolrzedna:" <<endl;
    cin >> p2;
*/

    }

Moduly.cpp

#include <iostream>
#include "naglowek.h"
using namespace std;

void Punkt1::wyswietl()
{

    cout << p1 <<endl;
    cout << p2 << endl;

}
0

Dlaczego usunąłeś definicję klasy (wtf), a zostawiłeś definicję konstruktora w nagłówku?

Z jakiego kursu korzystasz? Mam wrażenie, że nie rozumiesz o czym do ciebie piszemy i zmieniasz losowe fragmenty kodu licząc na to, że się uda.

1

Nie ma tam nic o podziale na pliki nagłówkowe i implementacyjne.

// deklaracja "istnieje c i jest klasą"
class c;
// definicja "c jest klasą o następującej budowie"
class c
{
public:
    int a;
    c(); // deklaracja "istnieje konstruktor domyślny klasy c"
};

// definicja "konstruktor domyślny klasy c robi to i to"
c::c()
{
}

Nie możesz mieć definicji funkcji (konstruktor jest funkcją) w nagłówku, więc przenieś ją do pliku .cpp.

3

Powinno być coś w rodzaju:

//punkt1.h
// zamiast strażnika można użyć #pragma once
#ifndef PUNKT1_H
#define PUNKT1_H
class Punkt1
{
	private:
    int p1,p2;
    void wyswietl();
	public:
    Punkt1();
};
#endif

//punkt2.h
#ifndef PUNKT2_H
#define PUNKT2_H
// zamiast strażnika można użyć #pragma once
class Punkt2
{
	private:
    int p1,p2;
	public:
    Punkt2();
};
#endif

//main.cpp
#include <iostream>
#include "punkt1.h"
#include "punkt2.h"
using namespace std;

int main()
{
    cout<<"Witaj!"<<endl;
    Punkt1 punkt1;
    Punkt2 punkt2;
    return 0;
}

//punkt1.cpp
#include <iostream>
#include "punkt1.h"
using namespace std;

Punkt1::Punkt1()
{
    std::cout<<"Domyslne wspolrzedne punktu to:"<<std::endl;
    wyswietl();
    p1=5;
    p2=4;
    std::cout<<"Wspolrzedne ustalone to: "<<std::endl;
    wyswietl();
}

void Punkt1::wyswietl()
{

    cout<<p1<<endl;
    cout<<p2<<endl;

}

//punkt2.cpp
#include <iostream>
#include "punkt2.h"
using namespace std;

Punkt2::Punkt2():p1(2),p2(4)
{
    cout<<"Wspolrzedne ustalone w drugim konstruktorze to: "<<endl;
    cout<<p1<<endl;
    cout<<p2<<endl;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1