zwracanie wartości

0

witam,
Napisałem klasy o podanej hierarchii dziedziczenia: A->B->E
klasy A i B nie mogą tworzyć obiektów. Dopóki Klasa E tworzyła sama pola name i className wszystko działało natomiast zmieniłęm że Klasa E dziedziczy name po A oraz className po B i program się wysypuje. Obiekty klasy liścia zapisuje w wektorze (<vector>). Obiekt jest dodawany normalnie natomiast jeśli próbuje zwrócić nazwę tego obiektu program się wysypuje. Dodam jeszcze, że klasa B dziedziczy wirtualnie po a ponieważ potem mam wielokrotne dziedziczenie po innych klasach.

 
class Aclass
{
protected:
    string className;
public:
virtual string getClassname();
virtual string getName();
virtual  string getStringToSave();
virtual void setClassName(string AclassName);
virtual void setInfo(string aInfo);
virtual  string getString();
};

class Bclass
: public virtual Aclass
{
protected:
    string name;
    string info;

public:
virtual string getClassname();
virtual string getName();
virtual  string getStringToSave();
virtual void setClassName(string AclassName);
virtual void setInfo(string aInfo);
virtual  string getString();
};

class Eclass
: public Bclass
{
public:
    string getName();
    string getClassname();
    Eclass(string name);
    string getStringToSave();
    void setClassName(string AclassName);
    void setInfo(string aInfo);
    string getString();
};

string Aclass::getString(){};
string Aclass::getStringToSave(){};
void Aclass::setClassName(string AclassName){};
void Aclass::setInfo(string aInfo){};
string Aclass::getName(){};
string Aclass::getClassname(){};


string Bclass::getString(){};
string Bclass::getStringToSave(){};
void Bclass::setClassName(string AclassName){};
void Bclass::setInfo(string aInfo){};
string Bclass::getName(){};
string Bclass::getClassname(){};


Eclass::Eclass(string name)
    {
        setClassName("Eclass");
        this->name = name;
        this->info = "brak informacji";
    }
string Eclass:: getStringToSave()
    {
        return className + "\t" + name + "\t" + info+ "\t";
    }

string Eclass:: getString()
    {
        return "nazwa klasy: " + className +" nazwa: " + name + " info: " + info;
    }
void Eclass::setClassName(string AclassName)
    {
        className=AclassName;
    }
void Eclass::setInfo(string aInfo)
    {
        this->info = aInfo;
    }
string Eclass::getName()
    {
        return this->name;
    }
string Eclass::getClassname()
    {
        return this->className;
    }




0

dodatkowo mam utworzoną klasę P w której mam ten oto właśnie vector do przechowywania tych obiektów. Poza tym wektorem w main mogę tworzyć obiekty normalnie i odczytywać z nich dane natomiast jak dodam je do vector to metody tamtych obiektów zapisanych w vector nie chcą mi zwrócić wartości.

oto jej funkcje


 void Panelclass:: addObject(string className,string name)
    {
        int classNum = classToNumber(className);
        switch(classNum)
        {
        case 1:{classList.emplace_back(new Eclass(name));break;}
        case 2:{classList.emplace_back(new Fclass(name));break;}
        case 3:{classList.emplace_back(new Gclass(name));break;}
        case 4:{classList.emplace_back(new Jclass(name));break;}
        case 5:{classList.emplace_back(new Kclass(name));break;}
        case 6:{classList.emplace_back(new Iclass(name));break;}
        }

    }


    int Panelclass:: searchObject(string name,string className)                   //szuka obiekt po nazwie i zwraca jego index w classList
    {
        for(int i=0;i<classList.size();i++)
        {
            if(classList[i]->getName()==name&&classList[i]->getClassname()==className)
            {

                return i;
            }
        }
        return -1;
    }


    string Panelclass:: removeObject(string name,string className)                  //usuwa obiekt na podstawie jego nazwy
    {
        int index=searchObject(name,className);
        if(index == -1)
        {
            return "nie ma takiego obiektu";
        }
        classList.erase(classList.begin()+index);
        return "usunieto";
    }

    string Panelclass:: modifyObject(string name,string info,string className)      //otrzymuje nazwe obiektu i zmienia jego informacje
    {
        int index = searchObject(name,className);
        if(index == -1){return "blad";}
        classList[index]->setInfo(info);
        return "zmodyfikowano";
    }
 
0

jak utworzę vector a main i dodam do niego obiekt tą samą metodą to również nie działa. To wina vector? jak można to naprawić? Użycie vector bardzo ułatwiłoby mi w tym przypadku

0

na pewno nie jest to wina vector.

Dla mnie problemem jest wyjasnienie problemu oraz tona nieczytelnego kodu.

Czytalem to dwa razy i za kazdym razem mialem ochote powiedziec tylko jedno "bierz debugger i sprawdzaj co masz nie tak"

Czy jestes w stanie zadac pytanie w 20 slowach oraz dac kod w max 20 linijkach (ktory jest czytelny) opisujacy Twoj problem?

0

Jestem dopiero początkującym programistą .Przepraszam trochę za haos spróbuje:
mam klasy które wstawiłęm. W klasie PanelClass mam metody służące do zapisywania usuwania oraz edycji vectora classList. W nim przechowuję obiekty klasy E. Dodawanie obiektu do vectora przebiega prawidłowo, natomiast jeśli próbuję się odwołać do metody obiektu zapisanego w nim (np. getString) to program wywołuje funkcje (sprawdzałem) natomiast nie chce mi zwrócić wartości które zawiera obiekt. Dla porównania w main stworzyłem sam obiekt klasy E i próbowałem zrobić to samo i działało.

Dodam jeszcze że na początku klasa E nie dziedziczyła pól po wyższych klasach tylko tworzyła je u siebie i działało wszystko włącznie z operacjami na niej w wektorze w klasie PanelClass.

0

w gruncie rzeczy chodzi mi o to że po dodaniu tego dziedziczonego pola (protected) funkcje z tego obiektu dodane do vectora jakby tracą do niego dostęp. W main natomiast mają go dalej.

0

Jak masz zadeklarowany ten vector wskaźników? Bo coś mi wyciekiem pamięci pachnie.

Podałeś to wszystko a nie podałeś jak próbujesz wywoływać te funkcje, ani działającej ani żadnej innej wersji. :P Poza tym, jak sprawdzałeś?

0

Dobra zacznę od początku i postaram się mniej haotycznie. Mam strukturę klas: A->B->E. funkcje deklaruje w klasie A, W poprzedniej wersji pola tworzyłęm prywatnie i tylko w klasie E i wtedy wszystko działało. Teraz pola deklaruję natomiast jedno w klasie A oraz jedno w B oba są typu protected. Klasa E dziedziczy więc 1 pole protected po A 1 pole protected po B oraz metody po A. Obiekty klasy E przechowuję w innej klasie P która ma vector prywatny o nazwie classList oraz metody typu add remove i modify do obsługi obiektów klasy E które są dodawane do tego vectora. Problem pojawia się gdy wywołuję metodę search klasy Panel ponieważ odwołuje się ona do metody getName klasy E. Metoda jest wywoływana bo sprawdzałem, program jednak się wysypuje ponieważ wygląda to tak jakby nie mógł zwrócić pola name które jest dziedziczone prywatnie po klasie A i zmienianie w konstruktorze klasy E na inną wartość. Nie wiem dokłądnie który kawałęk kodu wkleić więc napiszcie co będzie najistotniejsze :)

0

vector <unique_ptr<Aclass>> classList;

funkcję wywołuje następująco

    int Panelclass:: searchObject(string name,string className)                   //szuka obiekt po nazwie i zwraca jego index w classList
    {
        for(int i=0;i<classList.size();i++)
        {
            if(classList[i]->getName()==name&&classList[i]->getClassname()==className)
            {

                return i;
            }
        }
        return -1;
    } 

sprawdzałem poprzez dodanie cout przed return this->name;

 
string Eclass::getClassname()
    {
        return this->className;
    }
0

jak działały wywoływałem je dokładnie tak samo jedyna zmiana w programie to tylko te pola które teraz są dziedziczone po A i B były wtedy tworzone w E:)

0

Fiu, przynajmniej unique_ptr masz. To już coś. Ale w takim razie zamiast emplace_back(new Stuff) powinieneś raczej użyć push_back(make_unique<Stuff>(args)). Zaoszczędzi ewentualnego wycieku pamięci.

"Niedziałanie" objawia się błędem w czasie działania programu, tak? No to chyba wiem o co chodzi. ;) (...poczekaj kawalątek)

0

nom dokładnie tak :)

0

oki to czekam :) a jakiej biblioteki muszę użyć do make_unique ?

1

Okej, kawa wypita. :P

Skompilowałem sobie Twój kod, uzupełniony o rzeczy konieczne:

#include <iostream>
#include <string>
#include <memory>
#include <vector>
 
using namespace std;
 
class Aclass
{
protected:
    string className;
public:
virtual string getClassname();
virtual string getName();
virtual  string getStringToSave();
virtual void setClassName(string AclassName);
virtual void setInfo(string aInfo);
virtual  string getString();
};
 
class Bclass
: public virtual Aclass
{
protected:
    string name;
    string info;
 
public:
virtual string getClassname();
virtual string getName();
virtual  string getStringToSave();
virtual void setClassName(string AclassName);
virtual void setInfo(string aInfo);
virtual  string getString();
};
 
class Eclass
: public Bclass
{
public:
    string getName();
    string getClassname();
    Eclass(string name);
    string getStringToSave();
    void setClassName(string AclassName);
    void setInfo(string aInfo);
    string getString();
};
 
string Aclass::getString(){};
string Aclass::getStringToSave(){};
void Aclass::setClassName(string AclassName){};
void Aclass::setInfo(string aInfo){};
string Aclass::getName(){};
string Aclass::getClassname(){};
 
 
string Bclass::getString(){};
string Bclass::getStringToSave(){};
void Bclass::setClassName(string AclassName){};
void Bclass::setInfo(string aInfo){};
string Bclass::getName(){};
string Bclass::getClassname(){};
 
 
Eclass::Eclass(string name)
    {
        setClassName("Eclass");
        this->name = name;
        this->info = "brak informacji";
    }
string Eclass:: getStringToSave()
    {
        return className + "\t" + name + "\t" + info+ "\t";
    }
 
string Eclass:: getString()
    {
        return "nazwa klasy: " + className +" nazwa: " + name + " info: " + info;
    }
void Eclass::setClassName(string AclassName)
    {
        className=AclassName;
    }
void Eclass::setInfo(string aInfo)
    {
        this->info = aInfo;
    }
string Eclass::getName()
    {
        return this->name;
    }
string Eclass::getClassname()
    {
        return this->className;
    }
    
class Panelclass {
public:
    void addObject(string className, string name);
    int searchObject(string name, string className);
    string removeObject(string name, string className);
    string modifyObject(string name,string info,string className);
    int classToNumber(string name) { return 1; }
protected:
    vector <unique_ptr<Aclass>> classList;
};

void Panelclass:: addObject(string className,string name)
    {
        int classNum = classToNumber(className);
        switch(classNum)
        {
        case 1:{classList.emplace_back(new Eclass(name));break;}
        //case 2:{classList.emplace_back(new Fclass(name));break;}
        //case 3:{classList.emplace_back(new Gclass(name));break;}
        //case 4:{classList.emplace_back(new Jclass(name));break;}
        //case 5:{classList.emplace_back(new Kclass(name));break;}
        //case 6:{classList.emplace_back(new Iclass(name));break;}
        }
 
    }
 
 
    int Panelclass:: searchObject(string name,string className)                   //szuka obiekt po nazwie i zwraca jego index w classList
    {
        for(int i=0;i<classList.size();i++)
        {
            if(classList[i]->getName()==name&&classList[i]->getClassname()==className)
            {
                std::cout << "In: " << __PRETTY_FUNCTION__ << "\n" << classList[i]->getString() << "\n";
                return i;
            }
        }
        return -1;
    }
 
 
    string Panelclass:: removeObject(string name,string className)                  //usuwa obiekt na podstawie jego nazwy
    {
        int index=searchObject(name,className);
        if(index == -1)
        {
            return "nie ma takiego obiektu";
        }
        classList.erase(classList.begin()+index);
        return "usunieto";
    }
 
    string Panelclass:: modifyObject(string name,string info,string className)      //otrzymuje nazwe obiektu i zmienia jego informacje
    {
        int index = searchObject(name,className);
        if(index == -1){return "blad";}
        classList[index]->setInfo(info);
        return "zmodyfikowano";
    }
    

int main() {
    Panelclass p;
    string a = "Eclass", b = "bejb";
    p.addObject(a, b);
    std::cout << "found index: `" << p.searchObject(b, a) << "`";
}
 

I wyszło mi:

$ g++ --pedantic -Wall -Wextra hier.cpp -Wfatal-errors && ./a
hier.cpp: In member function 'virtual std::__cxx11::string Aclass::getString()':
hier.cpp:50:28: warning: no return statement in function returning non-void [-Wreturn-type]
 string Aclass::getString(){};
                            ^
hier.cpp: At global scope:
hier.cpp:50:29: warning: extra ';' [-Wpedantic]
 string Aclass::getString(){};
                             ^
hier.cpp: In member function 'virtual std::__cxx11::string Aclass::getStringToSave()':
hier.cpp:51:34: warning: no return statement in function returning non-void [-Wreturn-type]
 string Aclass::getStringToSave(){};
                                  ^
hier.cpp: At global scope:
hier.cpp:51:35: warning: extra ';' [-Wpedantic]
 string Aclass::getStringToSave(){};
                                   ^
hier.cpp: In member function 'virtual void Aclass::setClassName(std::__cxx11::string)':
hier.cpp:52:34: warning: unused parameter 'AclassName' [-Wunused-parameter]
 void Aclass::setClassName(string AclassName){};
                                  ^~~~~~~~~~
hier.cpp: At global scope:
hier.cpp:52:47: warning: extra ';' [-Wpedantic]
 void Aclass::setClassName(string AclassName){};
                                               ^
hier.cpp: In member function 'virtual void Aclass::setInfo(std::__cxx11::string)':
hier.cpp:53:29: warning: unused parameter 'aInfo' [-Wunused-parameter]
 void Aclass::setInfo(string aInfo){};
                             ^~~~~
hier.cpp: At global scope:
hier.cpp:53:37: warning: extra ';' [-Wpedantic]
 void Aclass::setInfo(string aInfo){};
                                     ^
hier.cpp: In member function 'virtual std::__cxx11::string Aclass::getName()':
hier.cpp:54:26: warning: no return statement in function returning non-void [-Wreturn-type]
 string Aclass::getName(){};
                          ^
hier.cpp: At global scope:
hier.cpp:54:27: warning: extra ';' [-Wpedantic]
 string Aclass::getName(){};
                           ^
hier.cpp: In member function 'virtual std::__cxx11::string Aclass::getClassname()':
hier.cpp:55:31: warning: no return statement in function returning non-void [-Wreturn-type]
 string Aclass::getClassname(){};
                               ^
hier.cpp: At global scope:
hier.cpp:55:32: warning: extra ';' [-Wpedantic]
 string Aclass::getClassname(){};
                                ^
hier.cpp: In member function 'virtual std::__cxx11::string Bclass::getString()':
hier.cpp:58:28: warning: no return statement in function returning non-void [-Wreturn-type]
 string Bclass::getString(){};
                            ^
hier.cpp: At global scope:
hier.cpp:58:29: warning: extra ';' [-Wpedantic]
 string Bclass::getString(){};
                             ^
hier.cpp: In member function 'virtual std::__cxx11::string Bclass::getStringToSave()':
hier.cpp:59:34: warning: no return statement in function returning non-void [-Wreturn-type]
 string Bclass::getStringToSave(){};
                                  ^
hier.cpp: At global scope:
hier.cpp:59:35: warning: extra ';' [-Wpedantic]
 string Bclass::getStringToSave(){};
                                   ^
hier.cpp: In member function 'virtual void Bclass::setClassName(std::__cxx11::string)':
hier.cpp:60:34: warning: unused parameter 'AclassName' [-Wunused-parameter]
 void Bclass::setClassName(string AclassName){};
                                  ^~~~~~~~~~
hier.cpp: At global scope:
hier.cpp:60:47: warning: extra ';' [-Wpedantic]
 void Bclass::setClassName(string AclassName){};
                                               ^
hier.cpp: In member function 'virtual void Bclass::setInfo(std::__cxx11::string)':
hier.cpp:61:29: warning: unused parameter 'aInfo' [-Wunused-parameter]
 void Bclass::setInfo(string aInfo){};
                             ^~~~~
hier.cpp: At global scope:
hier.cpp:61:37: warning: extra ';' [-Wpedantic]
 void Bclass::setInfo(string aInfo){};
                                     ^
hier.cpp: In member function 'virtual std::__cxx11::string Bclass::getName()':
hier.cpp:62:26: warning: no return statement in function returning non-void [-Wreturn-type]
 string Bclass::getName(){};
                          ^
hier.cpp: At global scope:
hier.cpp:62:27: warning: extra ';' [-Wpedantic]
 string Bclass::getName(){};
                           ^
hier.cpp: In member function 'virtual std::__cxx11::string Bclass::getClassname()':
hier.cpp:63:31: warning: no return statement in function returning non-void [-Wreturn-type]
 string Bclass::getClassname(){};
                               ^
hier.cpp: At global scope:
hier.cpp:63:32: warning: extra ';' [-Wpedantic]
 string Bclass::getClassname(){};
                                ^
hier.cpp: In member function 'int Panelclass::classToNumber(std::__cxx11::string)':
hier.cpp:104:30: warning: unused parameter 'name' [-Wunused-parameter]
     int classToNumber(string name) { return 1; }
                              ^~~~
hier.cpp: In member function 'int Panelclass::searchObject(std::__cxx11::string, std::__cxx11::string)': hier.cpp:127:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int i=0;i<classList.size();i++)
                     ~^~~~~~~~~~~~~~~~~
In: int Panelclass::searchObject(std::__cxx11::string, std::__cxx11::string)
nazwa klasy: Eclass nazwa: bejb info: brak informacji
found index: `0` 

No "niby" działa. To jednak nie wiem o co chodzi.
Te warningi to sobie weź do serca. W funkcji zwracającej wartość możesz nie mieć żadnego returna i to się skompiluje (bo i powinno!) - ale jeżeli w trakcie wykonywania kodu kiedykolwiek program znajdzie się w sytuacji, że "kontrola" dojdzie do końca ciała funkcji... To masz Undefined Behavior, demony z nosa, itd.

0
classList.push_back(make_unique<Eclass>(name))  

co jest źle w tym zapisie?

0

wielkie dzięki że się tak napracowałeś :) zaraz założe konto tylko po to żeby CI łapkę dać :)

0

czyli tak w sumie to co zmienić w tym kodzie? :)

1

A wyszły Ci błędy kompilacji? Jeśli tak - to je wklej, bo w myślach jeszcze nie czytam. :P
Podejrzewać jednak mogę, że Twój kompilator nie kompiluje domyślnie jako C++14, bo wtedy dodano make_unique. Dodaj -std=c++14 do linii kompilacji jeżeli używasz GCC.

Poza tym, to powyżej to takie freebie. Teraz Twoja kolej - obczaj w mojej sygnaturce co to jest SSCCE i się zastosuj. Obetnij wszystko co nie jest konieczne, aż dojdziesz do najmniejszej możliwej formy Twojego programu, która reprezentuje problem. Istnieje spora szansa, że w trakcie znajdziesz nie tylko problem ale i rozwiązanie.

A co zmienić? Że się tak technicznie wyrażę, a pierun go wi. U mnie się przecież nie wywala, więc teraz Twoja kolej - coś musimy robić inaczej, skoro wydaje się działać. Nic ważnego nie zmieniałem przecież, kod masz powyżej. ;)

0

tak wyszły jak próbowałem zmienić emplace_back na to co zaleciłeś :/
przed zmianą emplace_back wszytsko się kompilowało i błąd był wyrzucany w trakcie tak jak opisałem :/

0

Super, teraz wiem, że masz błędy kompilacji.

...dobrze by było, gdybyś je wkleił, bo jak już wspominałem, w myślach jeszcze nie czytam, a szklana kula akurat u mechanika. :P

0

a u Ciebie działa ok to co mi nie działało?

0

5a3cc8b588.png

0

Czytaj uważnie. Wkleiłem Ci kod i to jak go skompilowałem i to jak program został uruchomiony. Pod tymi wszystkimi ostrzeżeniami jest to co mi program wypluł:

In: int Panelclass::searchObject(std::__cxx11::string, std::__cxx11::string)
nazwa klasy: Eclass nazwa: bejb info: brak informacji
found index: `0`  

Czyli searchObject znalazła szukany obiekt, a co za tym idzie - dostęp przez vector zadziałał.

edit:
Czyli dobrze wyczytałem w myślach - w opcjach projektu ("Build options") wybierz C++14 jako standard języka, a jeśli nie ma takiej opcji - dodaj -std=c++14 w dodatkowych opcjach kompilacji ("Other compile options").

0

tak właśnie myślałęm tylko wolałem się upewnić. a zobacz jakbyś mógł czy funkcja modyfi Ci działa :)

0

Patrząc na kod, pewnie działa. (Ale to, że w parametrach wepchnąłeś info w środek to jakaś pomyłka jest. :P)

Uporasz się z C::B to sam sprawdzisz. ;)

0

Czyli czekaj bo się zgubiłem :) Mój kod bez znaczących zmian działą u Ciebie? Czy coś (i ewentualnie co :D) zmieniłeś i działą ?

0

Po raz kolejny (jejku, jakim ja dzisiaj cierpliwy :P) - wkleiłem Ci kod, który kompilowałem. To jest w przeważającej przerażającej większości Twój kod. (Nie poznajesz? :P) Dodałem nagłówki, "stuba" klasy Panelclass (ugh, dlaczego masz w nazwach klasy słowo "class"? Ty też masz "Heptanczłowiek" w dowodzie? :P) i funkcję main. No i troszeczkę info w metodzie searchObject. A, no i metodę classToNumber - też stub, bo nie mam zamiaru dodawać stupięćdziesięciu klas ABECADŁOclass:P

Porównaj ze swoim projektem - coś musisz robić inaczej niż ja mam w main.

I popraw te warningi. I podnieś sobie poziom ostrzeżeń - najlepiej w opcjach kompilatora dodaj sobie --pedantic -Wall -Wextra, bo kto wie ile jeszcze problemów Ci uciekło.

0

To ja nie wiem :/ Program który wkleiłeś i który u Ciebie działa u mnie tak samo się wysypuje :(

0

Jak się wysypuje? Konkretnie. ;)

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