Tablica elementów klasy bazowej

Tablica elementów klasy bazowej
0

witam,
Mam abstrakcyjną klasę bazową A oraz kilka klas dziedziczących po niej nazwijmy je B C D E. Chcę jak w javie stworzyć do nich jedną wspólną tablicę do zapisu da się zrobić coś takiego w cpp?

spartanPAGE
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
2

Tak.

0

A jak to zrobić ?

0

i jak to ewentualnie zrobić z wykorzystaniem vectora z biblioteki vector?

spartanPAGE
  • Rejestracja:prawie 12 lat
  • Ostatnio:3 dni
4
Kopiuj
#include <iostream>
#include <memory>
#include <vector>
using namespace std;

struct base {
	virtual void foo() {
		cout << "base" << endl;
	}
};

struct a: base {
	void foo() override {
		cout << "a" << endl;
	}	
};
struct b: base {
	void foo() override {
		cout << "b" << endl;
	}
};

int main() {
	vector<unique_ptr<base>> container;
	
	for(int i = 0; i < 5; ++i) {
		container.emplace_back(new a{});
		container.emplace_back(new b{});
	}
	
	for(auto &el: container) {
		el->foo();
	}
	return 0;
}

http://ideone.com/5RH6ji

edytowany 2x, ostatnio: spartanPAGE
0

d406071ee3.png

spartanPAGE
emplace_back, nie emplace
EvilOne
  • Rejestracja:prawie 14 lat
  • Ostatnio:22 dni
  • Postów:78
2

Na przyszłość wstawiaj swój kod w znaczniki i uważniej analizuj kod użytkowników, którzy Ci odpowiadają. Użyj emplace_back.

0

Ok dziękuje za pomoc tylko jest jeden problem mianowicie po dodaniu obiektu metodą emplace_back() wyskakuje mi błąd że podany obiekt nie posiada tej metody. Mam rozumieć że metoda emplace_back tworzy element klasy A za pomocą konstruktora klasy potomnej i obcina go z jego prywatnych pól?

HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

Nie mogę usunąć poprzedniego postu
Chodziło mi że po utworzeniu obiektu metodą emplace_back wywołując ten obiekt dostaje komunikat że podany obiekt nie posiada tego pola.

edit wszystko ok zapomniałem że muszę użyć -> zamiast .
post do zamknięcia dzięki za pomoc

edytowany 1x, ostatnio: Heptan
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0
Kopiuj
class Panelclass
{
private:
    vector <unique_ptr<Aclass>> classList;

public:
   void addObject(int classNum,string name)
    {
        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;}
        }

    }
    Aclass searchObject(string name)
    {
        for(int i=0;i<classList.size();i++)
        {
            cout<<classList[i]->getName();
            if(classList[i]->getName()==name)
            {
                return classList[i]
            }
        }
    }
 

funkcja ma za zadanie znaleźć obiekt o podanej nazwie i go zwrócić

dlaczego nie mogę zwrócić obiektu z vector?

edytowany 1x, ostatnio: Heptan
Xupicor
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 8 lat
1

Tutaj zwracasz przez kopię - czy masz zdefiniowany odpowiedni konstruktor kopiujący?

A może tak naprawdę chcesz zwrócić referencję? ;)


edytowany 1x, ostatnio: Xupicor
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

Nie mam , w której klasie należy go zdefiniować?

edit tak taki był pierwotny zamysł :)

edytowany 1x, ostatnio: Heptan
Xupicor
Zobacz update - może powinieneś zwrócić tam referencję? Albo wręcz zmienić unique_ptr na shared_ptr i zwrócić sprytny wskaźnik, albo zwrócić zwykły wskaźnik (no ale wtedy spytam - dlaczego nie referencję?)
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

powiem tak funkcja będzie później wykorzystywana do wyszukiwania obiektów i zmieniania ich zawartości. A Twoim zdaniem który sposób byłby najlepszy i najprostszy?

edytowany 1x, ostatnio: Heptan
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

Już coś mam tylko natrafiłem na nowy problem, jak zrobić żeby ta sama funkcja zwracała różne typy obiektu. W jednym przypadku będzie to klasa C w innym klasa D itd
z góry dzięki za pomoc i przepraszam że tak truję w niedziele :)

Xupicor
  • Rejestracja:ponad 16 lat
  • Ostatnio:ponad 8 lat
1

Na sposoby są sposoby, ale... Zastanów się, czy Ci to potrzebne w ogóle. Czy musisz dostać się do metod klas potomnych, które nie są wirtualne? Możesz podać przykład?


EvilOne
  • Rejestracja:prawie 14 lat
  • Ostatnio:22 dni
  • Postów:78
2
Heptan napisał(a):

powiem tak funkcja będzie później wykorzystywana do wyszukiwania obiektów i zmieniania ich zawartości. A Twoim zdaniem który sposób byłby najlepszy i najprostszy?

To zależy. Pierwsze podstawowe pytanie, czy bierzesz pod uwagę fakt nieznalezienia takiego obiektu? Twoja implementacja wskazuje na to, że nie.

Heptan napisał(a):

Już coś mam tylko natrafiłem na nowy problem, jak zrobić żeby ta sama funkcja zwracała różne typy obiektu. W jednym przypadku będzie to klasa C w innym klasa D itd
z góry dzięki za pomoc i przepraszam że tak truję w niedziele :)

Koniecznie musisz rozróżniać typy? Przemyśl to raz jeszcze. Rozwiązaniem tutaj może być po prostu polimorfizm i prawidłowe wykorzystanie funkcji wirtualnych do określonych operacji.

Xupicor
Odnośnie pierwszego paragrafu - good catch! I tu się może przydać zwracanie wskaźnika. --albo indeksu.
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

To może przedstawię koncepcję całego projektu:
Mam jedną abstrakcyjną klasę bazową po której dziedziczy kilka klas również abstrakcyjnych. Z tych klas dziedziczą klasy "liście" i tylko one mogą tworzyć obiekty. Stworzyłem osobną klasę Panel która przechowuje obiekty klas "liści" w vector. Chcę umożliwić poprzez metody tej klasy (Panel) dodawanie usuwanie oraz modyfikowanie obiektów klas "liści" dodanych do vectora.

HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0
Kopiuj
#include <iostream>
#include <string>
#include <vector>
#include "Aclass.h"
#include <memory>

using namespace std;



class Panelclass
{
private:
    vector <unique_ptr<Aclass>> classList;

public:
   void addObject(int classNum,string name)
    {
        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;}
        }

    } 

ok już rozwiązałem problem z wyszukiwaniem, po prostu będe zwracał index w vector. Ale żeby nie było za dobrze to wrócił mi natomiast błąd kompilacji przy dodawaniu nowego obiektu wyskakuje error"Aclass is anbiguos base of Fclass" co jest źle w tym kodzie ?

EvilOne
  • Rejestracja:prawie 14 lat
  • Ostatnio:22 dni
  • Postów:78
0

Teraz problem leży po stronie hierarchii dziedziczenia Twoich klas - dziedziczysz coś więcej niż jeden raz. Zamieść kod poglądowy ilustrujący tę hierarchię wtedy będzie nam łatwiej pomóc.

0

hierarchia jest trochę rozbudowana

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

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

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

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

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

class Fclass
: public Bclass,public Cclass
{
private:
    string name;
    string className;
    string info;
public:
    string getName();
    string getClassname();
    Fclass(string name);
    string getString();
    void setClassName(string AclassName);
    void setInfo(string aInfo);
};


class Gclass
: public Cclass
{
private:
    string name;
    string className;
    string info;
public:
    string getName();
    string getClassname();
    Gclass(string name);
    string getString();
    void setClassName(string AclassName);
    void setInfo(string aInfo);
};


class Hclass
: public Dclass
{
    public:
virtual string getName();
virtual string getClassname();
virtual string getString();
virtual void setClassName(string AclassName);
virtual void setInfo(string aInfo);
};

class Iclass
: public Dclass
{
private:
    string name;
    string className;
    string info;
public:
    string getName();
    string getClassname();
    Iclass(string name);
    string getString();
    void setClassName(string AclassName);
    void setInfo(string aInfo);
};
 
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

Jeżeli w main tworze obiekt to idzie bez problemu dopiero gdy tworzę go w vector to nie działa

dokładnie takie komunikaty wyskakują gdy próbuję to stworzyć w panel
<image>68523939f2.png</image>

edytowany 1x, ostatnio: Heptan
EvilOne
  • Rejestracja:prawie 14 lat
  • Ostatnio:22 dni
  • Postów:78
1

Teraz już wszystko jasne. Błąd Aclass is an ambiguous base of Fclass bierze się stąd:

Kopiuj
class Aclass {};
class Bclass : public Aclass {};
class Cclass : public Aclass {};
class Fclass : public Bclass, public Cclass {};

możesz ten problem rozwiązać dodając słówko virtual:

Kopiuj
class Aclass {};
class Bclass : virtual public Aclass {};
class Cclass : virtual public Aclass {};
class Fclass : public Bclass, public Cclass {};

albo raz jeszcze przemyśleć tę hierarchię.

HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

Oki już działa dzięki bardzo :)

PS dlaczego same wirtualne metody nie wystarcza?

carlosmay
  • Rejestracja:prawie 9 lat
  • Ostatnio:około 5 lat
  • Lokalizacja:Pabianice
1
Heptan napisał(a):

Oki już działa dzięki bardzo :)

PS dlaczego same wirtualne metody nie wystarcza?

Klasy B i C dziedziczą po wspólnej klasie bazowej A, a te są dziedziczone przez kolejną czyli F.
Zachodzi niejasność, poprzez którą klasa F ma dziedziczyć klasę A.

Metody wirtualne rozwiewają problem użycia metod, a tutaj potrzebujesz wirtualnego dziedziczenia klas.


edytowany 2x, ostatnio: carlosmay
HE
  • Rejestracja:ponad 8 lat
  • Ostatnio:ponad 8 lat
  • Postów:23
0

AA już rozumiem dzięki wszystkim za pomoc temat do zamknięcia ;)

edytowany 1x, ostatnio: Heptan
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)