Stałe z klasy podstawowej jako rozmiary tablic w klasie pochodnej

0

W klasie podstawowej kombinacje mam dwie stałe const:

const int liczba_sygnalow;
const int liczba_kombinacji;

inicjalizowane na liscie inicjalizacyjnej konstruktora tej klasy.

W klasie pochodnej linijka mam natomiast dwa składniki: tablicę string i tablicę int

string napis[liczba_kombinacji];
int priorytet[liczba_kombinacji];

Podczas kompilacji błąd "invalid use of non-static data member "kombinacje::liczba_kombinacji" from this location". Oczywiście na liście inicjalizacyjnej konstruktora klasy pochodnej linijka umieszczam wywołanie napomkniętego konstruktora klasy kombinacje.

Jakieś hipotezy? Propozycje, pomysły na diagnozę? ;)

0

Pokaż kod.

0

http://ideone.com/MgkX8X

jak chcesz mieć dynamicznie ustawiany rozmiar to użyj std::vector<T>

0
#ifndef KOMBINACJE_H
#define KOMBINACJE_H

#define WERSJA_ROBOCZA

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

/*
Ta klasa jest z zastosowania klasą abstrakcyjną. Dziedziczy ją klasa linijka. Nie zamierzamy definiować obiektu kombinacje,
bo po co definiować coś tak surowego? Jeżeli już, zróbmy linijki.
 */


class kombinacje
{
	public:
		// class constructor
		kombinacje::kombinacje(int liczba_s);
		// constructor kopiujacy musi byc zdefiniowany ze wzgledu na skladowe wskazniki
		kombinacje(const kombinacje & wzor);
		// class destructor
		~kombinacje();

		void poka_tablice(void);
		
		void zmien_nazwy(void);

	protected:
		const int liczba_sygnalow;
		const int liczba_kombinacji;
		
	private:
		int * tablica_pomiarowa;
		string * tablica_nazw_sygnalow;	// wskaznik na tablice string
		
		unsigned int potega(unsigned int a, unsigned int b);
};

#endif // KOMBINACJE_H

Funkcje kombinacje:

kombinacje::kombinacje(int liczba_s)
					: 	liczba_sygnalow (liczba_s),
						liczba_kombinacji ( potega(2, liczba_sygnalow))
{
	// wymus wpisanie nazw
	tablica_nazw_sygnalow = new string [liczba_sygnalow];
	zmien_nazwy(); 
	
	// dalej wymus wpisanie wynikow
	tablica_pomiarowa = new int [liczba_kombinacji];
	cout << "Podaj wyniki pomiarow: ";
	for (int i=0; i < liczba_kombinacji; i++)
	{
		cin >> *(tablica_pomiarowa + i);
	}
	cout << endl;
#ifdef WERSJA_ROBOCZA
	poka_tablice();
#endif // WERSJA_ROBOCZA
}
//************************************************************************
kombinacje::kombinacje(const kombinacje & wzor)
						:	liczba_sygnalow(wzor.liczba_sygnalow),
							liczba_kombinacji(wzor.liczba_kombinacji)
{
	tablica_nazw_sygnalow = new string [liczba_sygnalow];
	for(int i=0; i < liczba_sygnalow ; i++)
	{
		*(tablica_nazw_sygnalow + i) = *(wzor.tablica_nazw_sygnalow + i);
	}
	
	tablica_pomiarowa = new int [liczba_kombinacji];
	for(int i=0; i < liczba_kombinacji ; i++)
	{
		*(tablica_pomiarowa + i) = *(wzor.tablica_pomiarowa + i);
	}
}
//************************************************************************
void kombinacje::poka_tablice(void)
{
	for (int i=0; i < liczba_kombinacji; i++)
	{
		cout << *(tablica_pomiarowa + i) << ' ';
	}
}
//************************************************************************
void kombinacje::zmien_nazwy(void)
{
	string nazwa;
	for(int i=0; i < liczba_sygnalow; i++)
	{
		cout << "\nPodaj nazwe sygnalu " << i+1 << ": ";
		cin >> *(tablica_nazw_sygnalow + i);	//czyli typ string. Idealnie, bo taki zwraca 
										//bedacy stala doslowna C-string.
		#ifdef WERSJA_ROBOCZA
			cout << ' ' << *(tablica_nazw_sygnalow + i) << endl;
		#endif;
	}
}
//************************************************************************
unsigned int kombinacje::potega(unsigned int a, unsigned int b)
{
	unsigned int result(1);
	for( ; b > 0 ; b-- )
	{
		result *= a;
	}
	
	return result;
}
//************************************************************************
// class destructor
kombinacje::~kombinacje()
{
	#ifdef WERSJA_ROBOCZA
	cout << "\nZNISZCZENIE I SMIERC!!!";
	#endif // WERSJA_ROBOCZA
}

ciało klasy linijka:

ciało klasy linijka

#ifndef LINIJKA_H
#define LINIJKA_H
#include "kombinacje.h" // w srodku definicje string, iostream, using namespace.
#include <cmath>		//dla log, pow
#include <sstream>
/*
  Przechowuje linijke tekstu gotowa do wyswietlenia.
!!! Zdefiniowanie wymaga wywolania konstruktora obiektu klasy KOMBINACJE
 */
class linijka : public kombinacje		//odziedziczono: poka_tablice(); zmien_nazwy(); 
{
	
	public:
		/* dziedziczy:
		void poka_tablice(void);
			
		void zmien_nazwy(void);
		*/
		void wyswietl_napis (int nr_kombinacji)
		{
			cout << napis[nr_kombinacji] << endl;
		}
		
		int jaki_priorytet(int nr_kombinacji)
		{
			return priorytet[nr_kombinacji];
		}
		// class constructor
		linijka(int l_syg);
		
		// class destructor
		~linijka();
	private:		
		string napis[liczba_kombinacji];
		int priorytet[liczba_kombinacji];		//bedzie mialo znaczenie przy porzadkowaniu

		// liczba do stringu
		char*  liczba_na_napis(char *gdzie, int wartosc);
		// funkcja bada nr pomiaru, pisze czy sygnal wystepuje, liczy priorytet na liscie (0 - ilosc_sygnalow)
		int czy_sygnal(int nr_kombinacji, int ktory);
		
	
};

#endif // LINIJKA_H

funkcje linijka

// Class automatically generated by Dev-C++ New Class wizard

#include "linijka.h" // class's header file

// class constructor
linijka::linijka(int l_syg) :	kombinacje(l_syg)						
{
	for (int j=0; j < l_kombinacji; j++)
	{
		napis[j] = "Kombinacja: "
		bool czy_dac_plus = false;
		for(int i=0; i < liczba_sygnalow; i++)
		{
			if( ! czy_sygnal(j,i) ) continue;	// czy sygnal wystapil?
			priorytet[j]++;
			if(czy_dac_plus)
				{napis[j] += " + ";}
			else
				{napis[j] += " ";};
			napis[j] += *(tablica_nazw_sygnalow + i);
			
			czy_dac_plus = true;
		}
		napis[j] += " -> ";
		char tmp[20];
		napis[j] += liczba_na_napis(tmp, *(tablica_pomiarowa + nr_pomiaru));
	#ifdef WERSJA_ROBOCZA
		cout << endl << napis[j];
	#endif // WERSJA_ROBOCZA
	}	
}
//************************************************************************
//od 0 do 999
char*  linijka::liczba_na_napis(char *gdzie, int wartosc)
{
	int pozycja = 0 ;
	if(wartosc == 0)    gdzie[pozycja++] = '0' ;  // cyfra zero
	else
    {
		if(wartosc < 0)
		{
			gdzie[pozycja++] = '-' ; // wpisujemy znak minus
			wartosc = -wartosc ;    // i odtad pracujemy jak z liczba dodatnia     
		}
		
		int reszta = wartosc ;
		int pulap_dolny = (int) pow(10.0 , (int) log10((double) wartosc) ) ;
		// pulap dolny to najblizsza wartosc potegi 10 nie wieksza niz 
		// zadana wartosc. Np dla wartosci 852 pulap ten to jest 100  
		
		for( ; pulap_dolny > 0  ; pozycja++, pulap_dolny /= 10)
		{
			int cyfra = reszta / pulap_dolny ;
			reszta = reszta % pulap_dolny ;
			gdzie[pozycja] =  '0' + cyfra ;
		}
		
    } // end else
	
	gdzie[pozycja] =  0 ; // dopisz konczacy null;
	return gdzie ;
}
//************************************************************************
int linijka::czy_sygnal(int nr_kombinacji, int ktory)
{
	int maska = 1 << ktory;
	return (nr_kombinacji & maska); 
}
//************************************************************************
// class destructor
linijka::~linijka()
{
	cout << "\n DESTROY LINIJKA";
}
0

przerabiałem na klasy zadanie z działu wskaźników, z kombinacjami sygnałów wychwytywanymi przy powtarzaniu tych samych bodźców wiele razy. Jak ktoś czytał Grębosza to wie mniej więcej o co chodzi :D

0

Zobacz jak zrobione dwie tablice w klasie bazowej:

        int * tablica_pomiarowa;
        string * tablica_nazw_sygnalow;    // wskaznik na tablice string

i zrób tak samo.

0

Tak zatem zrobie. Dzięki, potrzebowałem potwierdzenia ploty o stałej znanej w trakcie kompilacji. A jeszcze jedno mnie ciekawi:

kombinacje::kombinacje(int liczba_s, int liczba_k) 
: enum {liczba_sygnalow = liczba_s, liczba_kombinacji = liczba_k}
{
//ciało konstruktora
}

da się tak?

0
mochu napisał(a):

Tak zatem zrobie. Dzięki, potrzebowałem potwierdzenia ploty o stałej znanej w trakcie kompilacji. A jeszcze jedno mnie ciekawi:

kombinacje::kombinacje(int liczba_s, int liczba_k) 
: liczba_sygnalow(liczba_s), liczba_kombinacji(liczba_k)
{
//ciało konstruktora
}

da się tak?

Tak się da (poprawiłem inline). Nie wiem skąd Ci się ten enum tam wziął

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